gpt4 book ai didi

java - JScrollPane 内的 JPanel 在滚动时出现图形故障

转载 作者:行者123 更新时间:2023-12-01 18:00:50 24 4
gpt4 key购买 nike

所以我制作了一个简单的图形 GUI,其中右侧部分是一个 JScrollPane,内部有一个 JPanel( Canvas )(mainGUI 类)。当我尝试绘制一些框(使用 Box 类)并运行它时,在滚动时出现重复的 windowsXP 图形错误,其中框渲染速度太慢或类似的情况,有点难以解释。如何在滚动后获得统一的无故障绘图?有渲染选项之类的吗?

代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class Grafin{
public static void main(String args[]){
mainGUI gui = new mainGUI();
}
}

class mainGUI{
private JFrame mainFrame;
private JPanel toolsPanel;
private JPanel canvasPanel;

public mainGUI(){
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
}catch(Exception e){
System.out.println(e.getMessage());
}

mainFrame = new JFrame("Grafin | untitled");
mainFrame.setLayout(new GridBagLayout());
mainFrame.setSize(920, 580);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);

loadGUI();
}

public void loadGUI(){
GridBagConstraints c = new GridBagConstraints();

//toolsPanel (izq) y canvasPanel (der) dentro de mainFrame
toolsPanel = new JPanel(new GridBagLayout());
toolsPanel.setPreferredSize(new Dimension(250,580));

c.gridx = 0;
c.gridy = 0;
c.weightx = 0.1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
mainFrame.add(toolsPanel, c);


canvasPanel = new JPanel(new GridBagLayout());
canvasPanel.setBackground(Color.white);
canvasPanel.setPreferredSize(new Dimension(1500,1000));

JScrollPane canvasScroll = new JScrollPane(canvasPanel);
canvasScroll.setPreferredSize(new Dimension(670,580));

c.gridx = 1;
c.gridy = 0;
c.weightx = 0.9;
mainFrame.add(canvasScroll, c);
canvasScroll.setSize(canvasScroll.getPreferredSize());
canvasScroll.setBackground(Color.white);

//CanvasPanel:
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 1;

Box b1 = new Box(10, 200, 30, 128);
Box b2 = new Box(200, 10, 120, 40);
canvasPanel.add(b1, c);
canvasPanel.add(b2, c);
mainFrame.pack();
}
}

class Box extends JPanel{
private Color borderColor;
private Color fillColor;
public int x;
public int y;
public int width;
public int height;

public Box(){
borderColor = Color.black;
fillColor = new Color(242, 242, 242);
x = y = 1;
width = height = 30;
}

public Box(int px, int py, int w, int h){
x = px;
y = py;
borderColor = Color.black;
fillColor = new Color(242, 242, 242);
width = w;
height = h;
}

public void changeFillColor(Color c){
fillColor = c;
}

public void changeBorderColor(Color c){
borderColor = c;
}

public void paint(Graphics g){
g.setColor(fillColor);
g.fillRect(x, y, width, height);
g.setColor(borderColor);
g.drawRect(x, y, width, height);
}
}

提前致谢节日快乐

最佳答案

首先,您覆盖了错误的绘画方法。您不应该重写 JPanel 的 Paint 方法,而应该重写其 PaintComponent 方法,因为这是一种更具体的绘制方法,并且默认情况下具有双缓冲,这在执行动画(您在滚动时执行的动画)时是一个优点。

更重要的是,您没有在覆盖中调用 super 的绘画方法,super.paintComponent(g)如果覆盖paintComponent,或super.paint(g)如果(错误地)覆盖油漆。这会阻止您的 JPanel 清理脏像素。

其他问题:您正在向使用 GridBagLayout 的组件添加两个组件,但对这两个组件使用完全相同的 GridBagConstraint,这是您不应该做的事情。

此外,您的 Box 类应该是一个逻辑类,而不是组件类。换句话说,它不应该扩展任何 Swing GUI 组件,并且应该在 canvasPanel 内绘制。

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Grafin2 extends JPanel {
private static final int PREF_W = 920;
private static final int PREF_H = 580;
private static final Dimension TOOLS_SIZE = new Dimension(250, PREF_H);
private static final Dimension CANVAS_SIZE = new Dimension(1500, 1000);
private JPanel toolsPanel = new JPanel();
private CanvasPanel canvasPanel = new CanvasPanel();

public Grafin2() {
MyBox box1 = new MyBox(10, 200, 30, 128);
MyBox box2 = new MyBox(200, 10, 120, 40);

box1.changeFillColor(new Color(255, 120, 120));
box2.changeFillColor(new Color(220, 220, 255));

canvasPanel.addMyBox(box1);
canvasPanel.addMyBox(box2);

toolsPanel.setPreferredSize(TOOLS_SIZE);
canvasPanel.setBackground(Color.white);
canvasPanel.setPreferredSize(CANVAS_SIZE);
JScrollPane canvasScroll = new JScrollPane(canvasPanel);

setLayout(new BorderLayout());
add(toolsPanel, BorderLayout.LINE_START);
add(canvasScroll, BorderLayout.CENTER);
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}

private class CanvasPanel extends JPanel {
// a collection to hold all the boxes
private List<MyBox> boxes = new ArrayList<>();

public void addMyBox(MyBox myBox) {
boxes.add(myBox);
}

@Override // again, this is the proper painting method
protected void paintComponent(Graphics g) {
super.paintComponent(g); // never forget this!
for (MyBox myBox : boxes) {
myBox.draw(g); // draw all the boxes that we hold
}
}
}

private static void createAndShowGui() {
Grafin2 mainPanel = new Grafin2();

JFrame frame = new JFrame("Grafin2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

// this is a logical class, **not** a component class.
class MyBox {
private Color borderColor;
private Color fillColor;
public int x;
public int y;
public int width;
public int height;

public MyBox() {
borderColor = Color.black;
fillColor = new Color(242, 242, 242);
x = y = 1;
width = height = 30;
}

public MyBox(int px, int py, int w, int h) {
x = px;
y = py;
borderColor = Color.black;
fillColor = new Color(242, 242, 242);
width = w;
height = h;
}

public void changeFillColor(Color c) {
fillColor = c;
}

public void changeBorderColor(Color c) {
borderColor = c;
}

public void draw(Graphics g) {
// no need to call a super method
// because there is none for this class
g.setColor(fillColor);
g.fillRect(x, y, width, height);
g.setColor(borderColor);
g.drawRect(x, y, width, height);
}
}

关于java - JScrollPane 内的 JPanel 在滚动时出现图形故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41083152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com