Java JPanel的背景是原来的两倍,但小组工作正常
关于代码:两个面板,一个用于绘图,另一个用于在颜色之间切换。我决定将切换器添加到框架的顶部。但是它的背景移到了底部,我可以在上面画画,因此它的背景超出了边界。若我将为中央JPanel设置一个边框,它的面板用于绘图,边框的顶部将加倍 我想将Jpanel添加到顶部,以便在绘图时在颜色之间切换。但顶级Jpanel背景是双倍的。但是如果我用通用面板替换Jpanel颜色,程序就会正常工作。我不知道为什么?请帮忙!如果您不明白,请尝试运行我用translater编写的这个问题的代码 JPanel背景加倍 进行自定义绘制时,方法中的第一条语句应为:Java JPanel的背景是原来的两倍,但小组工作正常,java,swing,jpanel,border,border-layout,Java,Swing,Jpanel,Border,Border Layout,关于代码:两个面板,一个用于绘图,另一个用于在颜色之间切换。我决定将切换器添加到框架的顶部。但是它的背景移到了底部,我可以在上面画画,因此它的背景超出了边界。若我将为中央JPanel设置一个边框,它的面板用于绘图,边框的顶部将加倍 我想将Jpanel添加到顶部,以便在绘图时在颜色之间切换。但顶级Jpanel背景是双倍的。但是如果我用通用面板替换Jpanel颜色,程序就会正常工作。我不知道为什么?请帮忙!如果您不明白,请尝试运行我用translater编写的这个问题的代码 JPanel背景加倍 进
package com.company;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayDeque;
import java.util.Random;
public class REcom {
REcom() {
JFrame jfm = new JFrame("Paint");
jfm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
BorderLayout border = new BorderLayout();
border.setVgap(10);
jfm.setLayout(border);
DrawPanel dw = new DrawPanel();
dw.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
dw.setXY(e.getX() , e.getY());
dw.repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
dw.previosPosition = new Position(e.getX() , e.getY());
}
});
jfm.add(dw ,BorderLayout.CENTER);
jfm.setBackground(Color.white);
jfm.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
jfm.setSize(500 ,500);
JPanel color = new JPanel(new FlowLayout(FlowLayout.LEFT));
//that Jpanel background is doubled
// color.setBounds(new Rectangle(0 ,0 , 100 , jfm.getHeight()));
Button blue = new Button();
blue.setBackground(Color.blue);
blue.setSize(500 ,200);
blue.addActionListener(e -> {
dw.color = Color.blue;
});
color.add(blue);
Button white = new Button();
white.setBackground(Color.white);
white.setSize(200 ,200);
white.addActionListener(e -> {
dw.color = Color.white;
});
color.add(white);
jfm.add(color , BorderLayout.NORTH);
jfm.setPreferredSize(new Dimension(500 ,500));
jfm.pack();
color.setBackground(Color.blue);
jfm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(REcom::new);
}
}
class DrawPanel extends JPanel {
ArrayDeque<Position> ad = new ArrayDeque<>();
Position previosPosition = null;
Color color = Color.yellow;
void setXY(int x , int y) {
ad.push(new Position(x , y));
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(color);
g2.setStroke(new BasicStroke(12f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
Position d = ad.pollLast();
if(d != null) {
if(previosPosition == null)
g2.fillOval(d.x, d.y -10 , d.x , d.y-10);
else{
g2.drawLine(previosPosition.x -5 , previosPosition.y -10 , d.x-5 , d.y-10);
}
previosPosition = d;
}
}
}
class Position {
int x, y;
Position(int x, int y) {
this.x= x;
this.y = y;
}
void setXY(int x , int y) {
this.x = x;
this.y = y;
}
}
若要清除背景,则可以使用绘画瑕疵,这就是为什么会看到两条蓝线
当然,当您添加super.paintcomponent时,由于背景已清除,因此绘画将消失
有两种解决方案:
保留要绘制的对象的ArrayList,并在paintComponent方法中迭代ArrayList以绘制所有对象
绘制缓冲区图像,然后只绘制整个图像。
我认为,在这种情况下,选择2可能是最好的
查看每种方法的更多信息和示例。听这个家伙说。他是一个百分之百的秋千专家。不是很多人喜欢他。实际上我建议不要选择第二种。如果你不自己处理,你会失去dpi的伸缩性。使用选项2,我可以实现撤销和恢复rendo@ErnarJack,我不知道有什么有效的方法可以撤消/重做。在示例代码中,addRectangle。。。。方法,然后在BuffereImage上绘制矩形。因此,如果希望能够撤消,则需要在每次更新图像之前保留BuffereImage的副本。如果对绘制的每个椭圆都执行此操作,这将导致大量内存需求,因为您需要保留BuffereImage的多个副本。因此,如果您关心的是撤消/重做,那么方法1就是一条出路。
super.paintComponent(g);