Java JPanel中的图形有问题,但它在一个框架中工作
我是新手,正在使用Cay Hortsmann的《大Java》一书来学习。对于早期的一个项目,我正在用GUI制作一个tic-tac-toe游戏,但是我很难让板显示在JPanel上。它只在框架中显示得很好,但是因为我想添加按钮,所以我尝试将板放在JPanel中,然后将JPanel添加到框架中。不幸的是,这不起作用。如果您能提供以下反馈,我将不胜感激:Java JPanel中的图形有问题,但它在一个框架中工作,java,swing,jpanel,tic-tac-toe,Java,Swing,Jpanel,Tic Tac Toe,我是新手,正在使用Cay Hortsmann的《大Java》一书来学习。对于早期的一个项目,我正在用GUI制作一个tic-tac-toe游戏,但是我很难让板显示在JPanel上。它只在框架中显示得很好,但是因为我想添加按钮,所以我尝试将板放在JPanel中,然后将JPanel添加到框架中。不幸的是,这不起作用。如果您能提供以下反馈,我将不胜感激: import javax.swing.JFrame; import javax.swing.JPanel; public class TicTa
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TicTacToePlayer {
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 400;
private int count = 0;
public static void main(String[] args) {
final JFrame frame = new JFrame();
// create board
final LinesComponent boardLines = new LinesComponent();
JPanel panel = new JPanel();
panel.add(boardLines);
frame.add(panel);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
public class LinesComponent extends JComponent {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Lines boardLines = new Lines();
boardLines.draw(g2);
}
}
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
public class Lines extends JComponent {
public Lines() {
setPreferredSize(new Dimension(400, 400));
}
public void draw(Graphics2D g2) {
Line2D.Double leftVertLine = new Line2D.Double(150, 50, 150, 350);
Line2D.Double rightVertLine = new Line2D.Double(250, 50, 250, 350);
Line2D.Double topHorizLine = new Line2D.Double(50, 150, 350, 150);
Line2D.Double bottomHorizLine = new Line2D.Double(50, 250, 350, 250);
g2.draw(leftVertLine);
g2.draw(rightVertLine);
g2.draw(topHorizLine);
g2.draw(bottomHorizLine);
}
}
面板的默认布局管理器是从左到右排列元素的
FlowLayout
。由于您希望网格显示在主视图中,因此可以考虑使用不同的布局管理器,如<代码>边界布局< /代码>。如果使用边框布局
,则可以将栅格放置到中心区域,以便栅格填充主视图:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
public class TicTacToePlayer {
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 400;
private int count = 0;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame();
// create board
final LinesComponent boardLines = new LinesComponent();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout(0, 0));
panel.add(boardLines, BorderLayout.CENTER);
frame.getContentPane().add(panel);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
要在使用BorderLayout
时向窗口添加按钮,可以将按钮添加到另一个JPanel
,并将该面板添加到其他区域之一的BorderLayout
(即:BorderLayout.NORTH
,BorderLayout.SOUTH
)中
另外,请注意,在上面更正的代码中,Swing GUI代码位于。您不应该在EDT之外运行任何Swing代码,因为大多数Swing对象方法都不是线程安全的
有关布局管理器的详细信息,请阅读。面板的默认布局管理器是一个从左到右排列元素的
FlowLayout
。由于您希望网格显示在主视图中,因此可以考虑使用不同的布局管理器,如<代码>边界布局< /代码>。如果使用边框布局
,则可以将栅格放置到中心区域,以便栅格填充主视图:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
public class TicTacToePlayer {
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 400;
private int count = 0;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame();
// create board
final LinesComponent boardLines = new LinesComponent();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout(0, 0));
panel.add(boardLines, BorderLayout.CENTER);
frame.getContentPane().add(panel);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
要在使用BorderLayout
时向窗口添加按钮,可以将按钮添加到另一个JPanel
,并将该面板添加到其他区域之一的BorderLayout
(即:BorderLayout.NORTH
,BorderLayout.SOUTH
)中
另外,请注意,在上面更正的代码中,Swing GUI代码位于。您不应该在EDT之外运行任何Swing代码,因为大多数Swing对象方法都不是线程安全的
有关布局管理器的更多信息,请阅读。让我们从明显的
使用JPanel
,该布局尊重添加到其中的组件的FlowLayout
首选大小
的默认大小为JComponent
,这意味着当您向其添加0x0
线路板时,它将被有效地设置为不可见且从不绘制。您可以通过使用
面板上的
边框布局
来创建此对话框,例如
JPanel面板=新的JPanel(new BorderLayout())代码>
- 虽然技术上不需要,但在执行自定义绘制时调用
始终是一个好的实践super.paintComponent
- 您不应该在
中创建短期对象,尤其是在状态没有任何变化的情况下(即,创建新实例的结果与创建的上一个实例的结果相同)paintComponent
可以在短时间内重复调用,这可能会对系统造成不必要的压力paintComponent
不需要从行
扩展,说真的,它什么都没做JComponent
- 使用
而不是pack
上的JFrame
,这将使生活更加轻松setSize
- Swing UI应该在事件调度线程的上下文中创建和操作
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TicTacToePlayer {
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 400;
private int count = 0;
public static void main(String[] args) {
new TicTacToePlayer();
}
public TicTacToePlayer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create board
final LinesComponent boardLines = new LinesComponent();
JPanel panel = new JPanel(new BorderLayout());
panel.add(boardLines);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class LinesComponent extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
draw(g2);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public void draw(Graphics2D g2) {
Line2D.Double leftVertLine = new Line2D.Double(150, 50, 150, 350);
Line2D.Double rightVertLine = new Line2D.Double(250, 50, 250, 350);
Line2D.Double topHorizLine = new Line2D.Double(50, 150, 350, 150);
Line2D.Double bottomHorizLine = new Line2D.Double(50, 250, 350, 250);
g2.draw(leftVertLine);
g2.draw(rightVertLine);
g2.draw(topHorizLine);
g2.draw(bottomHorizLine);
}
}
}
您应该考虑查看更多详细信息让我们从显而易见的
使用JPanel
,该布局尊重添加到其中的组件的FlowLayout
首选大小
的默认大小为JComponent
,这意味着当您向其添加0x0
线路板时,它将被有效地设置为不可见且从不绘制。您可以通过使用
面板上的
边框布局
来创建此对话框,例如
JPanel面板=新的JPanel(new BorderLayout())代码>
- 虽然技术上不需要,但在执行自定义绘制时调用
始终是一个好的实践super.paintComponent
- 您不应该在
中创建短期对象,尤其是在状态没有任何变化的情况下(即,创建新实例的结果与创建的上一个实例的结果相同)paintComponent
可以在短时间内重复调用,这可能会对系统造成不必要的压力paintComponent
不需要从行
扩展,说真的,它什么都没做JComponent
- 使用
而不是pack
上的JFrame
,这将使生活更加轻松setSize
- Swing UI应该在事件调度线程的上下文中创建和操作
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TicTacToePlayer {
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 400;
private int count = 0;
public static void main(String[] args) {
new TicTacToePlayer();
}
public TicTacToePlayer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create board
final LinesComponent boardLines = new LinesComponent();
JPanel panel = new JPanel(new BorderLayout());
panel.add(boardLines);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class LinesComponent extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
draw(g2);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public void draw(Graphics2D g2) {
Line2D.Double leftVertLine = new Line2D.Double(150, 50, 150, 350);
Line2D.Double rightVertLine = new Line2D.Double(250, 50, 250, 350);
Line2D.Double topHorizLine = new Line2D.Double(50, 150, 350, 150);
Line2D.Double bottomHorizLine = new Line2D.Double(50, 250, 350, 250);
g2.draw(leftVertLine);
g2.draw(rightVertLine);
g2.draw(topHorizLine);
g2.draw(bottomHorizLine);
}
}
}
你应该考虑看看更多细节