Especificación de la ubicación de Canvas en Swing
Frecuentes
Visto 3,157 veces
5
Estoy aprendiendo diseño de GUI de Swing. Una cosa que no he resuelto del todo es cómo agregar y agregar un Canvas
a una ubicación específica en un contenedor.
Más específicamente: creo un Canvas
clase que usa Paint
método. El objeto de esta clase se agrega a un Panel. Lo que no entiendo muy bien, es cómo y dónde se agrega a un Panel. En Tkinter Canvas
es un widget que contiene solo una imagen, pero en Swing no hay un widget similar (probablemente no sea la mejor palabra) agregado al marco que contiene solo el objeto Canvas y nada más.
Lo siento si es demasiado vago, estoy agregando un código autónomo. Ignore los campos de texto y las etiquetas.
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();
}
}
2 Respuestas
4
"Los programas de swing deben anular paintComponent()
en lugar de anular paint()
"-Pintar en AWT y Swing: los métodos de pintura. JPanel
or JComponent
son opciones comunes, como se sugiere aquí. Puede controlar la colocación utilizando un adecuado diseño.
Apéndice: ¿Cómo se relaciona esto con Canvas
?
La clase java.awt.Canvas
es un componente AWT; en su lugar, use el componente Swing javax.swing.JPanel
. Aquí hay una variación de su programa que simplemente selecciona un color aleatorio, pero podría darle una idea de cómo abordar sus otras propiedades. Hay un ejemplo relacionado aquí.
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);
}
}
}
contestado el 23 de mayo de 17 a las 13:05
¿Significa esto que tengo que llamar a un JPanel
objeto para la imagen? - Alex
¿Podría explicar por favor cómo se relaciona esto con el lienzo? - Romano C
@RomanC: Lo he explicado anteriormente, aunque (incorrectamente) pensé que le estaba respondiendo a Alex. Evitaría mezclar componentes AWT y Swing innecesariamente. - basurero
Canvas es un componente AWT. Es un "peso pesado", lo que significa que se empareja con una ventana nativa, una proporcionada por el sistema operativo. JPanel es un componente "ligero". Es completamente una abstracción de Swing. Los componentes pesados como Canvas tienen peculiaridades y es difícil trabajar con ellos. Algunos ejemplos son errores de cambio de tamaño y menús desplegables que desaparecen. Simplemente use JPanel a menos que tenga una razón absolutamente excelente para usar Canvas (como que es un JOGL GLCanvas y necesita la velocidad). - Gene
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java swing user-interface jframe jpanel or haz tu propia pregunta.
¿Qué sucedió? ¿No aceptaste mi solución? No aceptar motivo? - Roman C
+1 para sscce; Alex es libre de aceptar cualquier respuesta o ninguna. - trashgod