2012-08-24 99 views
5

我學習的Swing GUI設計。我還沒有弄清楚的一件事是如何添加一個Canvas到容器中的特定位置。指定畫布的位置在Swing

更具體地:我創建使用Paint方法的Canvas類。這個類的對象被添加到Panel中。我不太明白的是,它是如何以及在何處添加到面板的。在Tkinter Canvas是一個只包含圖像的小部件,但在Swing中,沒有類似的小部件(可能不是最好的單詞)添加到僅包含Canvas對象的幀中,而沒有其他任何東西。

很抱歉,如果它太模糊,我加入一個自包含的代碼。請忽略文本字段和標籤。

import java.awt.BorderLayout; 
import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JSeparator; 
import javax.swing.JTextField; 

//frame class 
class frame_class2 extends JFrame implements ActionListener{ 
    //declare buttons 
    JButton draw_button = new JButton("Draw"); 
    JButton quit_button= new JButton("Quit"); 
    JButton info_button = new JButton("Info"); 
    //declare labels 
    JLabel x_loc = new JLabel("X:"); 
    JLabel y_loc = new JLabel("Y:"); 
    JLabel w_label= new JLabel("Width:"); 
    JLabel h_label = new JLabel("Height:"); 
    //Layout 
    FlowLayout layout_frame1 = new FlowLayout(); 
    //Text boxes 
    JTextField x_loc_box = new JTextField("0"); 
    JTextField y_loc_box = new JTextField("0"); 
    JTextField w_loc_box = new JTextField("100"); 
    JTextField h_loc_box = new JTextField("100"); 
    //Info 
    JOptionPane info1 = new JOptionPane(); 
    //Canvas 
    //Canvas area1 = new Canvas(); 
    //Containers 
    JPanel panel1 = new JPanel(); 
    JPanel panel2= new JPanel(); 
    //Container container3 = new Container(); 
    Container con = getContentPane(); 


    public frame_class2(){  
    //panel1 = getContentPane(); 
    //add(area1); 
    //add labels to the first panel 
    panel1.setLayout(layout_frame1); 
    panel2.setLayout(layout_frame1); 
    panel1.add(x_loc); 
    panel1.add(x_loc_box); 
    panel1.add(y_loc); 
    panel1.add(y_loc_box); 
    panel1.add(w_label); 
    panel1.add(w_loc_box); 
    panel1.add(h_label); 
    panel1.add(h_loc_box); 
    //add buttons to the second panel 
    draw_button.addActionListener(this); 
    quit_button.addActionListener(this); 
    info_button.addActionListener(this); 
    panel2.add(draw_button); 
    panel2.add(quit_button); 
    panel2.add(info_button); 

    con.add(panel1, BorderLayout.NORTH); 
    //con.add(new JSeparator(), BorderLayout.CENTER); 

    con.add(panel2, BorderLayout.SOUTH); 
    setDefaultCloseOperation(super.EXIT_ON_CLOSE); 
    setTitle("Graphics Toolbox v2"); 
    //Set up the content pane. 
     //this.getContentPane(); 
    pack(); 
    //setSize(500, 500); 
    setLocationRelativeTo(null); 
    //setBackground(Color.BLUE); 
    setVisible(true); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
    // TODO Auto-generated method stub 
    if (e.getSource()==info_button){ 
     info1.showMessageDialog(this, "hahahahahaha"); 
    } 
    else if (e.getSource()==quit_button){ 
     System.exit(0); 
    } 
    else if (e.getSource()==draw_button){ 

     graphics_class2 input1 = new graphics_class2(); 
     con.add(input1);   
     //info1.showMessageDialog(this, "Not yet!"); 

    } 


    } 



} 

//graphics class 
class graphics_class2 extends Canvas{ 

    public graphics_class2(){ 
    //frame_class1 inst1 = new frame_class1(); 
    //Canvas img1 = inst1.area1; 
    setSize(50,50); 
    //setBackground(Color.BLUE); 
    } 

    public void paint(Graphics g){ 
    super.paint(g); 
    g.setColor(Color.GREEN); 
    g.fillArc(0, 0, 50, 50, 50, 50); 

    } 



} 



public class main_code { 

    public static void main(String args[]){ 
    frame_class2 inst1 = new frame_class2(); 
    } 



} 
+0

發生了什麼?你不接受我的解決方案嗎?不接受原因? –

+0

+1 [sscce](http://sscce.org/); Alex可以[接受任何答案或無](http://meta.stackexchange.com/a/5235/163188)。 – trashgod

回答

4

」Swing程序應該覆蓋paintComponent()而不是覆蓋paint()。「 - Painting in AWT and Swing: The Paint MethodsJPanelJComponent是常見的選擇,建議here。您可以使用合適的layout來控制展示位置。

附錄:請問這個涉及到Canvas

java.awt.Canvas是AWT組件;而是使用Swing組件javax.swing.JPanel。以下是您的程序的一個變體,它只是選擇一種隨機顏色,但它可能會讓您知道如何解決其他屬性。有一個相關示例here

image

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

public class MainCode { 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       MainView fc = new MainView(); 
      } 
     }); 
    } 

    private static class MainView implements ActionListener { 

     private JFrame f = new JFrame(); 
     private JButton colorButton = new JButton("Color"); 
     private JButton quitButton = new JButton("Quit"); 
     private JButton infoButton = new JButton("Info"); 
     private JLabel x_loc = new JLabel("X:"); 
     private JLabel y_loc = new JLabel("Y:"); 
     private JLabel w_label = new JLabel("Width:"); 
     private JLabel h_label = new JLabel("Height:"); 
     private JTextField x_loc_box = new JTextField("0"); 
     private JTextField y_loc_box = new JTextField("0"); 
     private JTextField w_loc_box = new JTextField("100"); 
     private JTextField h_loc_box = new JTextField("100"); 
     private JOptionPane info1 = new JOptionPane(); 
     private JPanel panel1 = new JPanel(); 
     private JPanel panel2 = new JPanel(); 
     private GraphicsClass graphicsClass = new GraphicsClass(); 

     public MainView() { 
      panel1.add(x_loc); 
      panel1.add(x_loc_box); 
      panel1.add(y_loc); 
      panel1.add(y_loc_box); 
      panel1.add(w_label); 
      panel1.add(w_loc_box); 
      panel1.add(h_label); 
      panel1.add(h_loc_box); 
      colorButton.addActionListener(this); 
      quitButton.addActionListener(this); 
      infoButton.addActionListener(this); 
      panel2.add(colorButton); 
      panel2.add(quitButton); 
      panel2.add(infoButton); 
      f.add(panel1, BorderLayout.NORTH); 
      f.add(graphicsClass, BorderLayout.CENTER); 
      f.add(panel2, BorderLayout.SOUTH); 
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      f.setTitle("Graphics Toolbox v2"); 
      f.pack(); 
      f.setLocationRelativeTo(null); 
      f.setVisible(true); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (e.getSource() == infoButton) { 
       JOptionPane.showMessageDialog(f, "hahahahahaha"); 
      } else if (e.getSource() == quitButton) { 
       System.exit(0); 
      } else if (e.getSource() == colorButton) { 
       graphicsClass.randomColor(); 
       graphicsClass.repaint(); 
      } 
     } 
    } 

    private static class GraphicsClass extends JPanel { 

     private static final int SIZE = 128; 
     private static final Random r = new Random(); 
     private Color color = Color.green; 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(SIZE, SIZE); 
     } 

     public void randomColor() { 
      this.color = new Color(r.nextInt()); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(color); 
      int w = getWidth(); 
      int h = getHeight(); 
      g.fillArc(0, h/4, w, h, 45, 90); 
     } 
    } 
} 
+0

這是否意味着我必須爲圖像調用一個單獨的'JPanel'對象? – Alex

+0

是的,我會覆蓋'JPanel'子類中的'paintComponent()'。另外,請參閱[示例](http://stackoverflow.com/a/7343420/230513)使用'BufferedImage' – trashgod

+0

您能解釋一下這與Canvas的關係嗎? –

1

將畫布追加到此面板的末尾。已將組件添加到已顯示的容器中,必須在該容器上調用validate以顯示新組件。 「

+0

我會避免沒有充分的理由動態添加組件。 – trashgod