我正在构建一个使用CardLayout在屏幕之间切换的GUI。我希望其中一个屏幕上有图形。我已经成功地能够使用GridLayout将矩形放置到面板上,并将该面板放置到主面板上,并且矩形清晰可见。但是,当我将该面板放到CardLayout面板上时,看不到矩形。将图形添加到CardLayout面板时,需要做些其他事情吗?
主要阶级
import java.awt.CardLayout;
import java.awt.Container;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
public class Window extends JFrame {
public Window() {
// Main Panel Configuration
Container panel = this.getContentPane();
panel.setLayout(new GridBagLayout());
panel.setSize(1000,1000);
GridBagConstraints gbc = new GridBagConstraints();
// GridBag Constraints
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridheight = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridx = 0;
gbc.gridy = 0;
// Button Tabs
JButton button1 = new JButton("button 1");
panel.add(button1, gbc);
JButton button2 = new JButton("button 2");
gbc.gridx = 1;
panel.add(button2, gbc);
// Panels for CardLayout
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
// Set Layout of Panels
panel1.setLayout(new GridBagLayout());
panel2.setLayout(new GridBagLayout());
// Set Dimensions of Panels
panel1.setSize(new Dimension(900, 500));
panel2.setSize(new Dimension(900, 500));
// Labels for panels
JLabel label1 = new JLabel("label 1");
gbc.gridx = 1;
gbc.gridy = 2;
panel1.add(label1, gbc);
JLabel label2 = new JLabel("label 2");
gbc.gridy = 2;
panel2.add(label2, gbc);
// TextFields for Panels
JTextField textField1 = new JTextField();
gbc.gridx = 2;
gbc.gridy = 2;
panel1.add(textField1, gbc);
JTextField textField2 = new JTextField();
gbc.gridy = 2;
panel2.add(textField2, gbc);
// Add Graphic to panel1
JPanel drawingPanel = new JPanel();
DrawingComponent dc = new DrawingComponent();
dc.setPreferredSize(new Dimension(100, 100));
drawingPanel.add(dc);
gbc.gridx = 0;
gbc.gridy = 3;
panel1.add(drawingPanel,gbc);
// Set TextField Dimensions
textField1.setPreferredSize(new Dimension(400, 20));
textField2.setPreferredSize(new Dimension(400, 20));
// CardLayout Panel for Entry Fields and Labels
JPanel cardLayoutPanel = new JPanel();
CardLayout c1 = new CardLayout();
cardLayoutPanel.setLayout(c1);
cardLayoutPanel.setSize(new Dimension(900, 600));
// Add Panels to CardLayout Panel
cardLayoutPanel.add("panel1",panel1);
cardLayoutPanel.add("panel2", panel2);
// Which panel to show First
c1.show(cardLayoutPanel, "panel1");
// Add CardLayout Panel to Main Panel
gbc.gridy = 1;
gbc.gridx = 0;
panel.add(cardLayoutPanel, gbc);
// Action Listeners Changing Between Tabs
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
c1.show(cardLayoutPanel, "panel1");
}
});
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
c1.show(cardLayoutPanel, "panel2");
}
});
setSize(800,600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args){
Window window = new Window();
}
}
图形组件类
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import java.awt.Rectangle;
public class DrawingComponent extends JComponent {
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Rectangle rect1 = new Rectangle(400, 400, 50, 50);
g2.draw(rect1);
}
}
答案 0 :(得分:2)
在这一部分:
JPanel drawingPanel = new JPanel();
DrawingComponent dc = new DrawingComponent();
dc.setPreferredSize(new Dimension(100, 100));
drawingPanel.add(dc);
您将DrawingComponent
的首选大小设置为(100,100)。然后,在绘制组件时,使用构造函数Rectangle(400, 400, 50, 50)
在Rectangle(int x, int y, int width, int height)
中绘制矩形。
话虽如此,我认为这是显而易见的。您的组件是100x100,但是您尝试在第400xx400th像素处进行绘制,这会导致在组件边界之外绘制矩形。
我不知道矩形的坐标应该是什么,但是如果要显示组件,请将矩形更改为Rectangle rect1 = new Rectangle(0, 0, 50, 50);
另外,当您使用override
paintComponent
方法时,VGR在注释中提到(他让我成为:P),请确保调用super.paintComponent()
。
最后,使用SwingUtilities#invokeLater
方法启动应用程序。
我对代码的含义之和:
public static class DrawingComponent extends JComponent {
public void paintComponent(Graphics g) {
super.paintComponent(g); // Should always start with super method.
Graphics2D g2 = (Graphics2D) g;
Rectangle rect1 = new Rectangle(0, 0, 50, 50);
g2.draw(rect1);
}
}
public static void main(String[] args) {
// All swing applications must run on their own thread named EDT (Event dispatch thread)
SwingUtilities.invokeLater(() -> {
Window window = new Window();
});
}
答案 1 :(得分:1)
一个问题是您正在绘制超出组件界限的图形。在组件本身被强制具有100×100的大小时,在(400,400)处绘制矩形将导致什么都看不到。
另一个问题是您试图显式设置组件和窗口的大小。但是对于这些尺寸而言,窗口还不够大。当GridBagLayout无法容纳其子项的首选大小时,它将“放弃”并将所有内容设置为其最小大小。由于DrawingComponent没有定义最小尺寸,因此它恢复为零宽度和零高度。 (您使用fill = HORIZONTAL强制其宽度等于其单元格的宽度,但高度仍为零。)
设置所有这些尺寸是不正确的。几乎永远没有理由调用setSize或setPreferredSize。
对于JTextField,您需要使用其setColumns方法设置其大小。
DrawingComponent类应该知道它想要的大小,并且应该通过重写其自己的getPreferredSize方法返回该大小。显然,它必须足够大以容纳自己的绘画:
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
对于面板和窗口,根本不要设置大小。如果您构建整个窗口,然后在其上调用pack(),则它们都将足够大以容纳其子组件。
同样,在代码中应该没有 no 调用setSize或setPreferredSize。您不需要它们。