调整窗口大小时,Java Swing绘图消失

我非常需要你的帮助,因为我无法独自解决这个问题。 我正在尝试创建一个GUI,并希望在按下按钮后在其中绘制一些东西,但我似乎有某种刷新/重新validation或线程问题。 绘图是绘制的,但是当我调整窗口大小时,绘画就会消失。 此外,当快速移动窗口时,部分图形会消失。 我尝试了很多东西,但是我无法解决这个问题,也许你可以帮助我。 我被指示不要编写自己的代码,但是使用NetBeans设计函数生成按钮和面板等。这可能会损害绘图过程/function,但我不知道。 我会给你发贴相关的代码,非常感谢你的建议(已经说明的东西只是我之前尝试过的文物,所以不要介意):

public class NewJFrame extends JFrame { public NewJFrame() { initComponents(); } @SuppressWarnings("unchecked") private void initComponents() { jButton1 = new javax.swing.JButton(); jPanel1 = new javax.swing.JPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setMinimumSize(new java.awt.Dimension(1200, 1000)); jButton1.setText("Draw"); jButton1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { jButton1ActionPerformed(evt); } }); GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGap(0, 1000, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGap(0, 0, Short.MAX_VALUE) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, 1000, Short.MAX_VALUE) .addGap(18, 18, 18) .addComponent(jButton1) .addGap(33, 33, 33)) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(0, 745, Short.MAX_VALUE) .addComponent(jButton1) .addGap(237, 237, 237)) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap()))) ); pack(); }//  private void jButton1ActionPerformed(ActionEvent evt) { Graphics g = jPanel1.getGraphics(); draw(jPanel1, g); } protected void paintComponent(Graphics g){ jPanel1.setSize(1000, 1000); Dimension d = jPanel1.getSize(); g.setColor(Color.BLACK); for (int i=0; i<=1000;i++){ if (i%100==0){ g.setColor(Color.RED); g.drawLine(i, d.height/2, i, (d.height/2)+100); } else if(i%50==0 && i%100!=0){ g.setColor(Color.BLUE); g.drawLine(i, d.height/2, i, (d.height/2)+100); } else { g.setColor(Color.BLACK); g.drawLine(i, d.height/2, i, (d.height/2)+100); } } g.setColor(Color.green); g.drawLine(0, d.height / 2, d.width, d.height / 2); } public void draw(JPanel Jpanel1, Graphics g) { System.out.println("wuffkowski"); Jpanel1.setSize(1000,1000); Dimension d = Jpanel1.getSize(); g.setColor(Color.BLACK); for (int i=0; i<=1000;i++){ if (i%100==0){ g.setColor(Color.RED); g.drawLine(i, d.height/2, i, (d.height/2)+100); } else if(i%50==0 && i%100!=0){ g.setColor(Color.BLUE); g.drawLine(i, d.height/2, i, (d.height/2)+100); } else { g.setColor(Color.BLACK); g.drawLine(i, d.height/2, i, (d.height/2)+100); } } g.setColor(Color.green); g.drawLine(0, d.height / 2, d.width, d.height / 2); Jpanel1.paintComponents(g); } public static void lala () { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { NewJFrame JF =new NewJFrame(); JF.setVisible(true); } }); } private javax.swing.JButton jButton1; private javax.swing.JPanel jPanel1; } 

再次感谢您宝贵的时间。

Java不记得为您绘制命令; 单击按钮时,图形将呈现一次,因为这是调用draw()的唯一时间。

如果要在resize后刷新渲染,请覆盖paint(Graphics)并在其中调用draw()

如果这与按钮单击有关,则必须在类中添加字段,在该类中您记住draw()需要的所有内容,包括是否应绘制任何内容:

 private boolean drawAtAll = false; private void jButton1ActionPerformed(ActionEvent evt) { drawAtAll = true; // ok to draw now draw(); } @Override public void paint(Graphics g) { super.paint(g); draw(); } public void draw() { if( !drawAtAll ) return; Graphics g = jPanel1.getGraphics(); ... } 

进一步阅读:

  • 课程:执行自定义绘画
  • 在AWT和Swing中绘画

尝试使用此代码,并询问可能出现的任何问题,在JPanel的paintComponent(…)方法中进行绘制。 您可以简单地覆盖所述组件的getPreferredSize() ,而不是每次为所述JComponent提供大小。 为了调用paintComponent(...)您只需编写repaint()而不是从程序中显式调用paintComponent(...) ,Swing将自动执行此操作。

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PaintingExample { private CustomPanel paintingPanel; private Timer timer; private int x = 1; private int y = 1; private ActionListener timerAction = new ActionListener() { public void actionPerformed(ActionEvent ae) { x++; y++; paintingPanel.setPosition(x, y); } }; private void createAndDisplayGUI() { JFrame frame = new JFrame("Painting Example"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); paintingPanel = new CustomPanel(); final JButton startStopButton = new JButton("STOP"); startStopButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { if (timer.isRunning()) { startStopButton.setText("START"); timer.stop(); } else if (!timer.isRunning()) { startStopButton.setText("STOP"); timer.start(); } } }); frame.add(paintingPanel, BorderLayout.CENTER); frame.add(startStopButton, BorderLayout.PAGE_END); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); timer = new Timer(100, timerAction); timer.start(); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new PaintingExample().createAndDisplayGUI(); } }); } } class CustomPanel extends JPanel { private int x = 0; private int y = 0; @Override public Dimension getPreferredSize() { return (new Dimension(800, 600)); } public void setPosition(int a, int b) { x = a; y = b; if (x <(getWidth() - 10) && y < (getHeight() - 10)) repaint(); else System.out.println("Nothing is happening..."); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.MAGENTA); g.fillOval(x, y, 10, 10); } } 

我没有完成你的所有代码,但是立即可见的是你不应该在不调用super.paintComponent情况下覆盖paintComponent方法。 而你注释掉的行调用super.paintComponents (注意s),这是不一样的。

我也不确定你在“调整窗口大小时”的含义,以及它与你的代码中出现的Jpanel1.setSize( 1000, 1000 )调用的关系。 您的布局管理器将负责面板的大小。 您不应将其设置为固定大小。

当您调整面板大小或更改其位置或最小化它并最大化它时,会调用paint(...)方法重新绘制内容。 你必须覆盖这个function,让它画出你的线条或者什么。 要做到这一点,您必须将绘图保存在数据结构中,以便能够在必要时重新绘制它。

这里描述了绘画方法。