Как получить доступ ко всем компонентам в топе JFrame
Частично в учебных целях я сделал JFrame
с 4 JPanel
с, 2 JLabel
с и JMenuBar
, Я поместил различные компоненты (кнопки, текстовые поля, текстовое поле) в 4 JPanels. Я отключил все компоненты.
Затем я написал два метода, чтобы попытаться включить все. Работал частично. Вот код:
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);
}
JTextArea
(внутри JScrollPane
) не включился даже с последними двумя строками выше. Зачем?
Я также попробовал:
Component [] s = jScrollPane1.getComponents();
for(Component ss: s)
ss.enableInputMethods(true);
Как включить текстовую область?
И JMenuBar
не включился либо. Но я действительно не знаю, где его найти. Я читал, что это в JLayeredPane, но... то, что я пробовал с ним, не сработало:
for(int i = 0; i < 2; i++){
System.out.println(i);
this.getLayeredPane().getComponent(i).setEnabled(true);
}
В какой панели я нахожу JMenuBar
и как бы я включил JMenu
s? (И даже JMenuItem
с.)
Конечно, это сработало:
menFileAndEdit.setEnabled(true);
mnuFile.setEnabled(true);
mnuEdit.setEnabled(true);
mniFileSave.setEnabled(true);
mniEditUndo.setEnabled(true);
mniEditRedo.setEnabled(true);
Имейте в виду, что я просто экспериментирую, пытаюсь узнать, где все находится и как получить к нему программный доступ, углубляясь с вершины. JFrame
используя что-то вроде getComponents()
,
1-е редактирование
Вот как можно попасть в строку меню!
Component[] m = this.getJMenuBar().getComponents();
for(Component mm: m)
mm.setEnabled(true);
2-й править
Ниже приведено рекурсивное частичное решение.
Это "рекурсивный ответ" на @maaartinus (хотя я только в эту секунду прочитал его заметку о стеке). Это не ответ на мою проблему, но это прогресс.
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");
}
Мне пришлось дважды позвонить, чтобы включить почти все:
gameBoard.enableEverything(gameBoard.getContentPane());
gameBoard.enableEverything(gameBoard.getJMenuBar());
Он покончил с одним методом, поскольку он рекурсивный, и он дал те же результаты, что и не включил JMenuItem
с или JTextArea
,
Поэтому я все еще ищу, как это сделать.
В результате получился интересный вывод, что каждый компонент кажется экземпляром контейнера, что выглядит неправильно:
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
Я надеялся, что рекурсия дойдет до JMenuItem
с, но нет такой удачи. Есть мысли о том, как это сделать?
4 ответа
Шесть месяцев спустя у меня есть приличный, не совсем неэлегичный способ получить доступ ко всему, что мне нужно, ниже основного JFrame, в контексте действия с опцией меню, которое устанавливает для всех подсказок ""
:
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);
}
Обратите внимание на рекурсивный вызов tipsOff
,
Также обратите внимание на комментарии и ответ об использовании ToolTipManager
(в этой теме, которая работает в контексте моего первоначального вопроса, чтобы свести весь код к одной строке. Суть в том, что любая "операция" может применяться вместо подсказок "-ing" - например, установка невидимого или отключение... так далее.
Спасибо Маартинусу за JScrollPane
линия в tipsOff
,
Я полагаю, вам нужно вернуть целое дерево, что-то вроде
- начать с корня
- перебрать все компоненты
- включить каждый из них
- проверить, является ли это экземпляром контейнера
- если это так, сделать рекурсивный вызов
Для ScrollPane
вам, вероятно, понадобится дополнительный instanceof
тест, а затем getViewPort
или что-то вроде этого.
"На какой панели я нахожу JMenuBar и как мне включить JMenus? (И даже JMenuItems".
Корневая панель JFrame
держит JMenuBar
,
JFrame.getRootPane().getJMenuBar();
Конечно, вы всегда можете просто позвонить JFrame.getJMenuBar()
без необходимости доступа к корневой панели.
Чтобы получить меню строки меню, вы можете JMenuBar.getSubElements
которые возвращают MenuElement[]
, JMenu
Также имеет getSubElements
, Имейте в виду, что MenuELement
может быть JMenu
или JMenuItem
и JMenu
может иметь больше слоев JMenus.
Так что вам нужно будет сделать несколько рекурсивных вызовов, если вы хотите попытаться получить к ним доступ таким образом.
Что касается попытки доступа к определенным типам компонентов, проверьте if (obj instanceof SomeComponentType)
поможет вам в том, что вы пытаетесь достичь.
Вот что сработало.
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);
}
Это позволяет каждому JMenuItem
в JMenu
menFileAndEdit
в JMenuBar
для формы.
Это оказалось намного сложнее, чем ожидалось, учитывая относительную легкость, с которой каждый второй элемент был включен при помощи рекурсии с использованием метода во втором редактировании исходного сообщения. Поэтому мне интересно, есть ли способ использовать рекурсивный метод для достижения этой цели.
Мне также интересно, есть ли способ использовать коллекцию на основе for
петля. Я попробовал пару вещей, но они не собирались.