removeAll在下次validation时不会删除?
有人可以解释为什么以下不能如我所料?
按下button'should'将导致只包含(空的)JScrollPane的显示,即input栏和button应该消失。 然而,他们留下来,直到组件被resize…
public static void main(String[] args) { JFrame frame = new JFrame("test"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); final JPanel panel = new JPanel(); Container cp = frame.getContentPane(); cp.setLayout(new FlowLayout()); cp.add(new JScrollPane(panel)); Component textField = new JTextField("i am input"); JButton button = new JButton(new AbstractAction("i am pressy") { @Override public void actionPerformed(ActionEvent e) { // this is already on the EDT panel.removeAll(); panel.revalidate(); } }); panel.setLayout(new FlowLayout()); panel.add(textField); panel.add(button); frame.pack(); frame.setVisible(true); }
谢谢你的帮助。 页。
更新可视化GUI时,代码应该是:
panel.revalidate(); panel.repaint(); // sometimes needed, this appears to be one of them
revalidate()
方法将组件标记为需要布局,但是直到某些事件触发repaint()
您将看不到任何更改。 调整父窗口的大小就是这样一个触发器。 切换应用程序是另一个 在以前的版本中 ,请注意面板上的setSize()
如何避免repaint()
的需要。 同样,这个例子改变了resetGame()
的布局。
“ AWT和Swing中的绘画”更详细。
import java.awt.EventQueue; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.WindowConstants; /** @see https://stackoverflow.com/questions/5812002 */ public class RevalidateTest { private static JPanel panel = new JPanel(); // default FlowLayout private static JTextField text = new JTextField("Text field"); private static JButton clear = new JButton(new AbstractAction("Clear") { @Override public void actionPerformed(ActionEvent e) { panel.removeAll(); panel.add(reset); panel.revalidate(); panel.repaint(); } }); private static JButton reset = new JButton(new AbstractAction("Reset") { @Override public void actionPerformed(ActionEvent e) { panel.removeAll(); panel.add(text); panel.add(clear); panel.revalidate(); panel.repaint(); } }); static void createAndShowGUI() { JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); panel.add(text); panel.add(clear); frame.add(panel); // default BorderLayout center frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } }
您可以panel.repaint()
的注释中的指定执行panel.repaint()
,但是,当您调整窗口大小时,UI仍会改变。 原因是从JPanel中删除元素会导致面板resize。 重绘操作不会导致面板resize,直到JFrame重新检查其布局为止(如调整窗口大小时)。
为了确保布局正确地布局在一个变化上,你可以调用frame.validate()
。 此操作将导致JFrame重新validation自身和所有子组件,这与窗口resize事件期间发生的操作是相同的。 要在您的代码中执行此方法,您需要将JFrame frame
更改为final,即,
final JFrame frame = new JFrame("test");