canvas 显示问题
Display troubles with canvas
目前我正在尝试拥有一个包含两个 JPanel
组件的 JFrame
- 第一个 JPanel
组件旨在包含用户可以单击以与之交互的各种按钮程序并将图像绘制到屏幕上。第二个,也是问题开始的地方,包含我试图绘制到的实际 Canvas
对象。
我遇到的问题是实际上并没有吸引第二个面板。我尝试了各种其他方法和检查,但一切都表明当前代码 应该 有效。
作为测试,我只是想在绘图面板上做一个 fillRect()
,但无济于事。这是我的代码:
//创建组件和 JFrame:
public static void createDisplay() {
JFrame f = new JFrame();//When JFrame flowlayout manager removed, the rectangle was drawn.
c = new Canvas();
width = 500;
height = 500;
f.setLayout(new FlowLayout());
f.add(addButtons()); //private method that covers the button panel
JPanel drawPanel = new JPanel();
drawPanel.add(c);
c.setFocusable(false);
f.add(drawPanel);
f.setPreferredSize(new Dimension(height, width));
lstnr = new Listeners();
f.addKeyListener(lstnr);
f.addMouseListener(lstnr);
f.addMouseMotionListener(lstnr);
f.setLocationRelativeTo(null);
f.pack();
f.setVisible(true);
}
以及实际绘制到屏幕的代码:
private void render() {
bs = c.getBufferStrategy();
if(bs == null) {
c.createBufferStrategy(3);
return;
}
do {
do {
g = bs.getDrawGraphics();
l.setGraphicsObj(g);
g.clearRect(0, 0, width, height);
for(Symbols s : l.getSymbolsArray());
s.renderSymbols();
}
g.fillRect(0, 0, 50, 50); //Just to test & make sure it works
g.dispose();
}while(bs.contentsRestored());
bs.show();
}while(bs.contentsLost());
}
现在我想再次强调,矩形 是在我从 createDisplay()
方法中删除 f.setLayoutManager(new FlowLayout());
片段时绘制的 。非常感谢任何帮助。
- 您的绘图系统存在冲突。一个被用来绘制
BufferStrategy
一个被 Swing 用来绘制它的组件
- 即使在最好的情况下,混合重量级组件和重量级组件也是有问题的,您应该尽一切可能减少重叠
- A
Canvas
的默认首选大小为 0x0
,FlowLayout
将使用它来确定最佳布局
一个 "possible" 解决方案可能是将 Canvas
放在它自己的位置并分离 Swing 元素。
您仍然 运行 陷入困境,因为您需要管理两个不同线程上下文之间的数据
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JButton;
import javax.swing.JFrame;
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();
}
PaintPane paintPane = new PaintPane();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ButtonPane(), BorderLayout.WEST);
frame.add(paintPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
paintPane.start();
}
});
}
public class ButtonPane extends JPanel {
public ButtonPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index =0; index < 5; index++) {
add(new JButton(Integer.toString(index)), gbc);
}
}
}
public class PaintPane extends Canvas {
private Thread renderThread;
private AtomicBoolean running = new AtomicBoolean(true);
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void start() {
if (renderThread != null) {
return;
}
running.set(true);
renderThread = new Thread(new Runnable() {
@Override
public void run() {
while (running.get()) {
render();
try {
Thread.sleep(5);
} catch (InterruptedException ex) {
}
}
}
});
renderThread.start();
}
public void stop() {
if (renderThread != null) {
return;
}
running.set(false);
renderThread.interrupt();
try {
renderThread.join();
} catch (InterruptedException ex) {
}
renderThread = null;
}
protected void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
do {
do {
Graphics g = bs.getDrawGraphics();
// :/
//l.setGraphicsObj(g);
g.clearRect(0, 0, getWidth(), getHeight());
//for (Symbols s : l.getSymbolsArray()) {
// // This is where g should be passed
// s.renderSymbols();
//}
g.setColor(Color.BLUE);
g.fillRect(0, 0, 50, 50); //Just to test & make sure it works
g.dispose();
} while (bs.contentsRestored());
bs.show();
} while (bs.contentsLost());
}
}
}
目前我正在尝试拥有一个包含两个 JPanel
组件的 JFrame
- 第一个 JPanel
组件旨在包含用户可以单击以与之交互的各种按钮程序并将图像绘制到屏幕上。第二个,也是问题开始的地方,包含我试图绘制到的实际 Canvas
对象。
我遇到的问题是实际上并没有吸引第二个面板。我尝试了各种其他方法和检查,但一切都表明当前代码 应该 有效。
作为测试,我只是想在绘图面板上做一个 fillRect()
,但无济于事。这是我的代码:
//创建组件和 JFrame:
public static void createDisplay() {
JFrame f = new JFrame();//When JFrame flowlayout manager removed, the rectangle was drawn.
c = new Canvas();
width = 500;
height = 500;
f.setLayout(new FlowLayout());
f.add(addButtons()); //private method that covers the button panel
JPanel drawPanel = new JPanel();
drawPanel.add(c);
c.setFocusable(false);
f.add(drawPanel);
f.setPreferredSize(new Dimension(height, width));
lstnr = new Listeners();
f.addKeyListener(lstnr);
f.addMouseListener(lstnr);
f.addMouseMotionListener(lstnr);
f.setLocationRelativeTo(null);
f.pack();
f.setVisible(true);
}
以及实际绘制到屏幕的代码:
private void render() {
bs = c.getBufferStrategy();
if(bs == null) {
c.createBufferStrategy(3);
return;
}
do {
do {
g = bs.getDrawGraphics();
l.setGraphicsObj(g);
g.clearRect(0, 0, width, height);
for(Symbols s : l.getSymbolsArray());
s.renderSymbols();
}
g.fillRect(0, 0, 50, 50); //Just to test & make sure it works
g.dispose();
}while(bs.contentsRestored());
bs.show();
}while(bs.contentsLost());
}
现在我想再次强调,矩形 是在我从 createDisplay()
方法中删除 f.setLayoutManager(new FlowLayout());
片段时绘制的 。非常感谢任何帮助。
- 您的绘图系统存在冲突。一个被用来绘制
BufferStrategy
一个被 Swing 用来绘制它的组件 - 即使在最好的情况下,混合重量级组件和重量级组件也是有问题的,您应该尽一切可能减少重叠
- A
Canvas
的默认首选大小为0x0
,FlowLayout
将使用它来确定最佳布局
一个 "possible" 解决方案可能是将 Canvas
放在它自己的位置并分离 Swing 元素。
您仍然 运行 陷入困境,因为您需要管理两个不同线程上下文之间的数据
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JButton;
import javax.swing.JFrame;
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();
}
PaintPane paintPane = new PaintPane();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ButtonPane(), BorderLayout.WEST);
frame.add(paintPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
paintPane.start();
}
});
}
public class ButtonPane extends JPanel {
public ButtonPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index =0; index < 5; index++) {
add(new JButton(Integer.toString(index)), gbc);
}
}
}
public class PaintPane extends Canvas {
private Thread renderThread;
private AtomicBoolean running = new AtomicBoolean(true);
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void start() {
if (renderThread != null) {
return;
}
running.set(true);
renderThread = new Thread(new Runnable() {
@Override
public void run() {
while (running.get()) {
render();
try {
Thread.sleep(5);
} catch (InterruptedException ex) {
}
}
}
});
renderThread.start();
}
public void stop() {
if (renderThread != null) {
return;
}
running.set(false);
renderThread.interrupt();
try {
renderThread.join();
} catch (InterruptedException ex) {
}
renderThread = null;
}
protected void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
do {
do {
Graphics g = bs.getDrawGraphics();
// :/
//l.setGraphicsObj(g);
g.clearRect(0, 0, getWidth(), getHeight());
//for (Symbols s : l.getSymbolsArray()) {
// // This is where g should be passed
// s.renderSymbols();
//}
g.setColor(Color.BLUE);
g.fillRect(0, 0, 50, 50); //Just to test & make sure it works
g.dispose();
} while (bs.contentsRestored());
bs.show();
} while (bs.contentsLost());
}
}
}