Partly for learning purposes, I made a JFrame
with 4 JPanel
s, 2 JLabel
s, and a JMenuBar
. I put various components (buttons, textboxes, textarea) into the 4 JPanels. I disabled every one of the components throughout.
I then wrote two methods to try to enable everything. Worked partially. Here's the code:
public void enableEverything(){
Component [] p = this.getContentPane().getComponents();
for(Component pp : p)
if(pp instanceof JPanel)
enableAll((JPanel) pp);
}
public void enableAll(JPanel p){
Component [] c = p.getComponents();
for(Component cc: c)
cc.setEnabled(true);
jTextArea1.setEnabled(true);
jScrollPane1.setEnabled(true);
}
The JTextArea
(inside a JScrollPane
) didn't get enabled even with the last two lines above. Why?
I also tried:
Component [] s = jScrollPane1.getComponents();
for(Component ss: s)
ss.enableInputMethods(true);
How do I enable the textarea?
And the JMenuBar
didn't get enabled either. But I really don't know where to find it. I read that it's in the JLayeredPane, but ... what I tried with it didn't work:
for(int i = 0; i < 2; i++){
System.out.println(i);
this.getLayeredPane().getComponent(i).setEnabled(true);
}
In which pane do I find the JMenuBar
and how would I enable the JMenu
s? (And even the JMenuItem
s.)
Of course, this worked:
menFileAndEdit.setEnabled(true);
mnuFile.setEnabled(true);
mnuEdit.setEnabled(true);
mniFileSave.setEnabled(true);
mniEditUndo.setEnabled(true);
mniEditRedo.setEnabled(true);
Keep in mind that I'm just experimenting, trying to learn where everything is and how to access it programmatically by drilling down from the top JFrame
using something like getComponents()
.
Here's how to get at the menu bar!
Component[] m = this.getJMenuBar().getComponents();
for(Component mm: m)
mm.setEnabled(true);
See below for recursive partial solution.
This is a "recursive response" to @maaartinus (though I only just this second read his note about a stack). It's not an answer to my problem, but it's progress.
public void enableEverything(Container c){
Component [] p = c.getComponents();
System.out.println("Component count " + c.getComponentCount() + " for " +
c.toString().substring(0,40) );
for(Component pp : p){
pp.setEnabled(true);
if(pp instanceof Container){
System.out.println("Recursive call for " + pp.toString().substring(0,40));
enableEverything((Container) pp);
}
else System.out.println("No recursive call");
}
I had to call it twice to get almost everything enabled:
gameBoard.enableEverything(gameBoard.getContentPane());
gameBoard.enableEverything(gameBoard.getJMenuBar());
It did away with one method since it's recursive, and it produced same results in that it also did NOT enable the JMenuItem
s or the JTextArea
.
So I'm still looking for how to do that.
It produced interesting output in that every component seems to be an instance of Container, which doesn't seem right:
gameBoard.enableEverything(gameBoard.getContentPane())
Component count 6 for javax.swing.JPanel[null.contentPane,0,23
Recursive call for javax.swing.JPanel[pnlGameGrid,12,139,59
Component count 1 for javax.swing.JPanel[pnlGameGrid,12,139,59
Recursive call for javax.swing.JTextField[jTextField1,233,1
Component count 0 for javax.swing.JTextField[jTextField1,233,1
Recursive call for javax.swing.JPanel[pnlAvailableLetters,1
Component count 1 for javax.swing.JPanel[pnlAvailableLetters,1
Recursive call for javax.swing.JToggleButton[jToggleButton1
Component count 0 for javax.swing.JToggleButton[jToggleButton1
Recursive call for javax.swing.JLabel[lblAvailableLetters,1
Component count 0 for javax.swing.JLabel[lblAvailableLetters,1
Recursive call for javax.swing.JPanel[pnlScore,476,25,107x9
Component count 2 for javax.swing.JPanel[pnlScore,476,25,107x9
Recursive call for javax.swing.JTextField[txtScore,21,14,66
Component count 0 for javax.swing.JTextField[txtScore,21,14,66
Recursive call for javax.swing.JButton[btnScore,21,61,66x24
Component count 0 for javax.swing.JButton[btnScore,21,61,66x24
Recursive call for javax.swing.JPanel[pnlPlays,624,51,271x5
Component count 3 for javax.swing.JPanel[pnlPlays,624,51,271x5
Recursive call for javax.swing.JScrollPane[jScrollPane1,13,
Component count 3 for javax.swing.JScrollPane[jScrollPane1,13,
Recursive call for javax.swing.JViewport[,1,1,220x80,layout
Component count 1 for javax.swing.JViewport[,1,1,220x80,layout
Recursive call for javax.swing.JTextArea[jTextArea1,0,0,220
Component count 0 for javax.swing.JTextArea[jTextArea1,0,0,220
Recursive call for javax.swing.JScrollPane$ScrollBar[,0,0,0
Component count 2 for javax.swing.JScrollPane$ScrollBar[,0,0,0
Recursive call for javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for javax.swing.JScrollPane$ScrollBar[,0,0,0
Component count 2 for javax.swing.JScrollPane$ScrollBar[,0,0,0
Recursive call for javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for javax.swing.plaf.metal.MetalScrollButton
Component count 0 for javax.swing.plaf.metal.MetalScrollButton
Recursive call for javax.swing.JButton[jButton1,61,262,81x2
Component count 0 for javax.swing.JButton[jButton1,61,262,81x2
Recursive call for javax.swing.JCheckBox[jCheckBox1,49,207,
Component count 0 for javax.swing.JCheckBox[jCheckBox1,49,207,
Recursive call for javax.swing.JLabel[lblPlays,624,29,100x1
Component count 0 for javax.swing.JLabel[lblPlays,624,29,100x1
gameBoard.enableEverything(gameBoard.getJMenuBar())
Component count 2 for javax.swing.JMenuBar[menFileAndEdit,0,0,
Recursive call for javax.swing.JMenu[mnuFile,0,0,31x21,alig
Component count 0 for javax.swing.JMenu[mnuFile,0,0,31x21,alig
Recursive call for javax.swing.JMenu[mnuEdit,31,0,33x21,ali
Component count 0 for javax.swing.JMenu[mnuEdit,31,0,33x21,ali
I was hoping recursion would get at the JMenuItem
s, but no such luck. Any thoughts on how to do so?
I guess you need to recurse the whole tree, something like
For the ScrollPane
you'll probably need an additional instanceof
test and then getViewPort
or something like this.
"In which pane do I find the JMenuBar and how would I enable the JMenus? (And even the JMenuItems."
The Root Pane of the JFrame
holds the JMenuBar
.
JFrame.getRootPane().getJMenuBar();
Of course you can always just call JFrame.getJMenuBar()
, without having to access the root pane.
To get the menus of the menu bar, you can can JMenuBar.getSubElements
which return the MenuElement[]
. JMenu
Also has getSubElements
. Keep in mind though that a MenuELement
can be JMenu
or a JMenuItem
, and a JMenu
can have more layers of JMenus.
So you will have to do some recursive calling if you wanted to try to access them this way.
As for trying to access specific component types, check if (obj instanceof SomeComponentType)
will help you in what you are trying to achieve.
Here's what worked.
for(int i = 0; i < menFileAndEdit.getMenuCount(); i++){
menFileAndEdit.getMenu(i).setEnabled(true);
Component [] cc = menFileAndEdit.getMenu(i).getMenuComponents();
for(Component c : cc)
c.setEnabled(true);
}
That enables each JMenuItem
in JMenu
menFileAndEdit
in the JMenuBar
for the form.
That was a lot harder than expected, given the relative ease with which every other element was enabled by recursion using the method in the second edit of the original post. So I wonder if there's a way to use the recursive method to accomplish this.
I also wonder if there's a way to use a collection-based for
loop. I tried a couple of things but they wouldn't compile.
Six months later, I have a decent, not-altogether-inelegant way to access everything that I needed to below main JFrame, in the context of a menu option action that sets all tool tips to ""
:
private void tipsOff(Container container)
{
Component [] c = container.getComponents();
Component s;
for (Component cc : c) {
((JComponent)cc).setToolTipText("");
if(cc instanceof JPanel) tipsOff((Container) cc);
if(cc instanceof JScrollPane) tipsOff(((JScrollPane)cc).getViewport());
}
}
private void mniPrefTooltipsActionPerformed(java.awt.event.ActionEvent evt)
{
tipsOff(gui.getContentPane());
tipsOff(gui.mbrMenuBar);
}
Note recursive call to tipsOff
.
Also note comments and Answer about using ToolTipManager
(in this thread , which works in the context of my original question to reduce all the code to one line. Point here is that any other operation could be applied instead of ""-ing tool tips--eg, setting invisible or disabling... etc.
Thanks to maaartinus for the JScrollPane
line in tipsOff
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.