我在 paintcomponent 方法中的 JLabel 和 GUI 代码没有同时绘制
My JLabel and GUI code in a paintcomponent method do not draw at the same time
当我尝试绘制 JLabel 或我的 GUI 时,我最后添加到 JFrame 的任何内容都会被绘制,而其余部分永远不会被绘制或覆盖。如果您能帮助我找到在特定位置连同我的 GUI 绘制 JLabel 的解决方案,我将不胜感激。我听说过布局以及它如何帮助我,但是有很多不同的人对这个主题有不同的看法。这是我的代码。
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.JPanel;
import javax.swing.JFrame;
import static java.lang.System.*;
import java.awt.event.*;
import java.awt.Graphics.*;
public class Main extends JPanel
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double w = screenSize.getWidth();
double h = screenSize.getHeight();
static JFrame f = new JFrame("Tic-Tac-Toe");
static JPanel p = new JPanel();
int width = (int)w;
int height = (int)h;
int width1a = width/2 - 300;
int width2a = width/2 - 100;
int width3a = width/2 + 100;
int width4a = width/2 + 300;
int height1from = (int)height - 100;
int height1to = (int)height - (int)(height/1.05);
public void paintComponent(Graphics g)
{
super.paintComponent(g);
JLabel l = new JLabel("Hello World !");
f.add(l);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g.setColor(Color.black);
g2.drawLine(width1a, height1from, width1a, height1to);
g2.drawLine(width2a, height1from, width2a, height1to);
g2.drawLine(width3a, height1from, width3a, height1to);
g2.drawLine(width4a, height1from, width4a, height1to);
}
public static void main(String[] args)
{
Main m = new Main();
f.setSize(400,300);
f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JLabel l = new JLabel("Hello World !");
f.add(p);
f.add(m);
}
}
如果我不清楚或有任何问题,请告诉我。我只希望 JLabel 和 GUI 绘图出现在 JFrame 上。请随时提出任何我应该重做的建议,感谢您抽出宝贵时间!
您永远不会从绘制方法中向组件添加组件。你永远不应该在 paint 方法中以任何方式修改组件的状态,绘画是为了绘画,没有别的。
参见 Painting in AWT and Swing 和
Performing Custom Painting 有关在 Swing 中绘画如何工作的更多详细信息...
您正在将三个组件添加到 BorderLayout
中的同一位置,一般情况下,通常只会显示最后一个组件,因为它是由 BorderLayout
[= 管理的组件22=]
有关详细信息,请参阅 Laying Out Components Within a Container and How to Use BorderLayout。
您还应该确保您是在事件调度线程的上下文中创建 UI,有关详细信息,请参阅 Initial Threads
绘制也与被绘制的组件相关,也就是说,0x0
是组件的左上角,任何超出组件可视范围的绘制都会丢失。
你也应该避免使用 static
,一般来说,这很好地表明你的设计有问题,它在 UI 中变得特别混乱。如果你真的想听我抱怨 static
的邪恶,请查看
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JPanel blue = new JPanel();
blue.setBackground(Color.BLUE);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel("Hello world"), BorderLayout.NORTH);
frame.add(new TestPane());
frame.add(blue, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
add(new JLabel("Hello World"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// This could actually be achieved using a EmptyBorder and a LineBorder
// but this demonstrates the point...
g2d.setColor(Color.RED);
g2d.drawRect(10, 10, getWidth() - 20, getHeight() - 20);
g2d.dispose();
}
}
}
当我尝试绘制 JLabel 或我的 GUI 时,我最后添加到 JFrame 的任何内容都会被绘制,而其余部分永远不会被绘制或覆盖。如果您能帮助我找到在特定位置连同我的 GUI 绘制 JLabel 的解决方案,我将不胜感激。我听说过布局以及它如何帮助我,但是有很多不同的人对这个主题有不同的看法。这是我的代码。
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.JPanel;
import javax.swing.JFrame;
import static java.lang.System.*;
import java.awt.event.*;
import java.awt.Graphics.*;
public class Main extends JPanel
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double w = screenSize.getWidth();
double h = screenSize.getHeight();
static JFrame f = new JFrame("Tic-Tac-Toe");
static JPanel p = new JPanel();
int width = (int)w;
int height = (int)h;
int width1a = width/2 - 300;
int width2a = width/2 - 100;
int width3a = width/2 + 100;
int width4a = width/2 + 300;
int height1from = (int)height - 100;
int height1to = (int)height - (int)(height/1.05);
public void paintComponent(Graphics g)
{
super.paintComponent(g);
JLabel l = new JLabel("Hello World !");
f.add(l);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g.setColor(Color.black);
g2.drawLine(width1a, height1from, width1a, height1to);
g2.drawLine(width2a, height1from, width2a, height1to);
g2.drawLine(width3a, height1from, width3a, height1to);
g2.drawLine(width4a, height1from, width4a, height1to);
}
public static void main(String[] args)
{
Main m = new Main();
f.setSize(400,300);
f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JLabel l = new JLabel("Hello World !");
f.add(p);
f.add(m);
}
}
如果我不清楚或有任何问题,请告诉我。我只希望 JLabel 和 GUI 绘图出现在 JFrame 上。请随时提出任何我应该重做的建议,感谢您抽出宝贵时间!
您永远不会从绘制方法中向组件添加组件。你永远不应该在 paint 方法中以任何方式修改组件的状态,绘画是为了绘画,没有别的。
参见 Painting in AWT and Swing 和 Performing Custom Painting 有关在 Swing 中绘画如何工作的更多详细信息...
您正在将三个组件添加到 BorderLayout
中的同一位置,一般情况下,通常只会显示最后一个组件,因为它是由 BorderLayout
[= 管理的组件22=]
有关详细信息,请参阅 Laying Out Components Within a Container and How to Use BorderLayout。
您还应该确保您是在事件调度线程的上下文中创建 UI,有关详细信息,请参阅 Initial Threads
绘制也与被绘制的组件相关,也就是说,0x0
是组件的左上角,任何超出组件可视范围的绘制都会丢失。
你也应该避免使用 static
,一般来说,这很好地表明你的设计有问题,它在 UI 中变得特别混乱。如果你真的想听我抱怨 static
的邪恶,请查看
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JPanel blue = new JPanel();
blue.setBackground(Color.BLUE);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel("Hello world"), BorderLayout.NORTH);
frame.add(new TestPane());
frame.add(blue, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
add(new JLabel("Hello World"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// This could actually be achieved using a EmptyBorder and a LineBorder
// but this demonstrates the point...
g2d.setColor(Color.RED);
g2d.drawRect(10, 10, getWidth() - 20, getHeight() - 20);
g2d.dispose();
}
}
}