2012-04-30 79 views
1

我需要你的帮助,因为我自己无法解决这个问题。 我想创建一个图形用户界面,并希望在按下按钮后绘制一些东西,但我似乎有某种刷新/重新验证或线程问题。绘图是绘制的,但是当我调整窗口大小时,绘画消失。另外,当窗口很快移动时,图形的一部分就会消失。我尝试了很多东西,但是我无法解决这个问题,也许你可以帮助我。我被指示不要自己写代码,而是使用NetBeans Design函数来生成按钮和面板等。也许这会损害绘图过程/功能,但我不知道。我会后你的相关代码,并会提供建议非常感激(的outcommented东西都是从我以前试过只是假象,所以不介意吧):当调整窗口大小时,Java Swing绘图消失

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(); 
    }// </editor-fold> 

    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; 
} 

再次感谢了很多你宝贵的时间。

+0

请了解[Java命名约定](http://www.oracle.com/technetwork/java/codeconv-138413.html),并坚持给他们:-) –

回答

5

Java不记得为你绘制命令;当你点击按钮时,你的图形会被渲染一次,因为这是调用draw()的唯一时间。

如果要在调整大小后刷新渲染,请覆盖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(); 
    ... 
} 

延伸阅读:

+0

感谢您的建议,我只是在尝试;有道理你提到。但现在的结果是:调整窗口大小时仍然绘画消失,但不总是;)。有时在调整大小后,绘图仍然存在。我会试着改变一些事情,告诉你,结果是什么。谢谢。 – user1365291

+0

绘画并不像看起来那么简单。阅读我提到的两篇文章。他们将帮助你理解正在发生的事情。之后,你应该更加简单地找到并解决你的问题。 –

+0

再次感谢大家的帮助,我投这个为“答案”,因为基本上涂装方法的覆盖是我现在使用的,但其他答案也很有帮助。然而,我仍然在作弊以避免这个消失的问题:由于我使用NetBeans的设计部分来使用Swing,因此我没有选中我的JPanel的水平可调整大小和垂直可调整大小的按钮,它与覆盖绘制方法的重写和固定我的JFrame的最小尺寸(正如我告诉过你的,我仍然不能完全信任我的布局管理器),它完成了这项工作。再次感谢你。 – user1365291

0

调整面板大小或改变位置或最小化位置并使其最大化时,会调用paint(...)方法重新绘制内容。你必须覆盖这个功能,让它画上你的线条或任何东西。为此,您必须将绘图保存在数据结构中,以便在必要时重新绘制它。

涂料方法描述here

+0

非常感谢你和我我会读到这些东西,并尝试以某种方式更好地管理事情。 – user1365291

2

我没有浏览所有的代码,但是可以立即看到的是,您不应该覆盖paintComponent方法而不会调用super.paintComponent。并且你的注释行号码super.paintComponents(注意s),这是不一样的。

我也不确定你的意思是'当我调整窗口大小'时,以及如何将你的代码中出现的Jpanel1.setSize(1000, 1000)调用连接在一起。您的布局管理器将处理面板的大小。您不应该将其设置为固定大小。

+0

非常感谢,我会尝试并回答你是否有效。外面评论的东西只是表明,我不知道该把什么东西放在哪里以及使用什么:p。所以我只是通过垃圾邮件发送了不同的东西,这些东西可能有助于在代码的不同位置看到变化。但没有任何帮助:编辑:当我删除所有set.Size方法,什么都没有被绘制了;)。这个我从未与之合作的图形界面的东西真的让我疯狂^^。 – user1365291

+0

Ahha也是如此,但仔细观察整个事情,我意识到他并不是在重写'paintComponent(...)'方法,这只是一个邪恶的名字给他自己的个人方法,因为他继承了'JFrame'和I猜猜它没有这样的方法 –

+0

是的,你是对的,我不能调用这个方法,似乎我真的不会调用paintComponent方法^^。根据你的回答和下面的内容,当我不为JFrame设置一个尺寸时,覆盖paint方法似乎“工作”,但是第一个绘图立即绘制而没有按下按钮,并且位于Frame的顶部。此外,有关按钮的布局是邪恶的。但我会试着让你知道,不管它是否奏效。 – user1365291

4

试一试这段代码,并询问可能出现的任何问题,在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); 
    } 
} 
相关问题