2012-08-24 8 views
5

Uczę się projektowania GUI Swing. Jedną z rzeczy, których nie do końca wyjaśniłem, jest dodanie dodania Canvas do określonej lokalizacji w kontenerze.Określanie położenia płótna w Swing

Dokładniej: Tworzę klasę Canvas, która wykorzystuje metodę Paint. Obiekt tej klasy jest dodawany do panelu. Czego nie rozumiem, to jak i gdzie jest dodawany do panelu. W Tkinter Canvas jest widżetem zawierającym tylko obraz, ale w Swingu nie ma podobnego widgetu (prawdopodobnie nie najlepszego słowa) dodanego do ramki zawierającej tylko obiekt Canvas i nic więcej.

Przepraszam, jeśli jest zbyt nieprecyzyjny, dodaję samowystarczalny kod. Ignoruj ​​pola tekstowe i etykiety.

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

Co się stało? Nie zaakceptowałeś mojego rozwiązania? Przyczyna nieakceptowana? –

+0

+1 dla [sscce] (http://sscce.org/); Alex może dowolnie [akceptować dowolną odpowiedź lub jej brak] (http://meta.stackexchange.com/a/5235/163188). – trashgod

Odpowiedz

4

"Programy przechylające powinny zastąpić paintComponent() zamiast przesłonić paint()." - Painting in AWT and Swing: The Paint Methods. JPanel lub JComponent są często wybierane, zgodnie z sugestią here. Możesz kontrolować rozmieszczenie przy użyciu odpowiedniego layout.

Dodatek: Jak to się ma do Canvas?

Klasa java.awt.Canvas jest składnikiem AWT; zamiast tego użyj komponentu Swing javax.swing.JPanel. Oto odmiany twojego programu, który wybiera losowy kolor, ale może dać ci pomysł, jak zaadresować inne właściwości. Istnieje powiązany przykład: 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

Czy to oznacza, że ​​muszę wywołać osobny obiekt 'JPanel' dla obrazu? – Alex

+0

Tak, zastąpiłbym 'paintComponent()' w podklasie 'JPanel'. Alternatywnie, zobacz ten [przykład] (http://stackoverflow.com/a/7343420/230513) używając 'BufferedImage' – trashgod

+0

Czy możesz wyjaśnić, jak to się ma do płótna? –

1

Dołącza kanwę do końca tego panelu. Do kontenera, który został wyświetlony, został dodany komponent, należy go wywołać na tym kontenerze, aby wyświetlić nowy komponent.

+0

Unikałbym dynamicznego dodawania komponentów bez ważnego powodu. – trashgod