gpt4 book ai didi

java - 大型 JPanel 上的绘制字符串在 Linux 上变得困惑,但在 Windows 上却不然

转载 作者:行者123 更新时间:2023-12-02 02:47:17 24 4
gpt4 key购买 nike

我在 Graphics drawString 方法上遇到了问题。简而言之,我观察到 Linux 上 drawString 的意外行为,如果面板尺寸很大,字符串会变得困惑。

举个例子。我修改了 Oracle 中的 ScrollDemo2 类以在 drawingPane 上绘制字符串:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class ScrollDemo2 extends JPanel
{
private Dimension area;
private JPanel drawingPane;

public ScrollDemo2() {
super(new BorderLayout());

area = new Dimension(100000,1000);

drawingPane = new DrawingPane();
drawingPane.setBackground(Color.white);
drawingPane.setPreferredSize(area);
drawingPane.revalidate();
drawingPane.repaint();

JScrollPane scroller = new JScrollPane(drawingPane);
scroller.setPreferredSize(new Dimension(500,500));

add(scroller, BorderLayout.CENTER);
}

public class DrawingPane extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// drawString gives correct results in Windows but gives messy strings in Linux; drawLine gives correct lines in both Windows and Linux
for (int i = 0; i < 100000; i += 100)
g.drawString("Mark " + i, i, 20);
for (int i = 0; i < 100000; i += 100)
g.drawLine(i, i % 1000 / 10 + 25, i, i % 1000 / 10 + 35);

}

}


private static void createAndShowGUI() {
JFrame frame = new JFrame("ScrollDemo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JComponent newContentPane = new ScrollDemo2();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

程序在 Windows 7 上运行

程序在 Windows 7 上显示正确的字符串。

程序在Linux 14.04上运行

该程序在 Linux 上显示困惑的字符串。

除了drawString方法之外,还添加了drawLine方法,并且drawLine方法在Windows和Linux下都可以正常工作。

这是为什么呢?在Linux上应该如何重写代码来解决这个问题?

最佳答案

如评论中所述,如果绘制静态(稳定不变的背景图像),请使用 BufferedImage。例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class ScrollDemo2B extends JPanel
{
private static final int IMG_W = 100000;
private static final int IMG_H = 1000;
// private Dimension area;
private JPanel drawingPane;
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);

public ScrollDemo2B() {
super(new BorderLayout());

Graphics2D g2 = img.createGraphics();
g2.setColor(Color.BLACK);
for (int i = 0; i < 100000; i += 100) {
g2.drawString("Mark " + i, i, 20);
}
for (int i = 0; i < 100000; i += 100) {
g2.drawLine(i, i % 1000 / 10 + 25, i, i % 1000 / 10 + 35);
}
g2.dispose();

drawingPane = new DrawingPane();
drawingPane.setBackground(Color.white);
drawingPane.revalidate();
drawingPane.repaint();

JScrollPane scroller = new JScrollPane(drawingPane);
scroller.setPreferredSize(new Dimension(500,500));

add(scroller, BorderLayout.CENTER);
}

public class DrawingPane extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
int w = img.getWidth();
int h = img.getHeight();
return new Dimension(w, h);
}

}


private static void createAndShowGUI() {
JFrame frame = new JFrame("ScrollDemo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JComponent newContentPane = new ScrollDemo2B();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

然后,如果您有移动 Sprite 或动态图像,您可以在paintComponent方法中绘制它们。

关于java - 大型 JPanel 上的绘制字符串在 Linux 上变得困惑,但在 Windows 上却不然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44394681/

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