2012-04-30 81 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); 
    } 
} 
相關問題