Java drawRect()不是';在某些颜色上不能正常工作

Java drawRect()不是';在某些颜色上不能正常工作,java,swing,graphics2d,Java,Swing,Graphics2d,我总是用这样的轮廓创建矩形(使用图形(2D): 这很好用,除了一些颜色,如Color.BLUE。有些线条的厚度不同: 乍一看可能很难看到,但如果你仔细观察,你会发现左边的线太粗,右边的线太细。其他颜色也会出现这种情况,只是不太明显:(我仍然不确定青色是否会出现这种情况,无法准确判断) 我无法理解这一点,因为黑线只是画在内部蓝色矩形上,内部矩形不应该对其产生影响。(没有fillRect()线的厚度均匀) 我在下面提供了一个示例,它可能会帮助您更好地看到差异。我的问题:为什么某些RGB颜色会出现

我总是用这样的轮廓创建矩形(使用
图形
2D
):

这很好用,除了一些颜色,如
Color.BLUE
。有些线条的厚度不同:

乍一看可能很难看到,但如果你仔细观察,你会发现左边的线太粗,右边的线太细。其他颜色也会出现这种情况,只是不太明显:(我仍然不确定青色是否会出现这种情况,无法准确判断)

我无法理解这一点,因为黑线只是画在内部蓝色矩形上,内部矩形不应该对其产生影响。(没有
fillRect()
线的厚度均匀)

我在下面提供了一个示例,它可能会帮助您更好地看到差异。我的问题:为什么某些RGB颜色会出现这种情况,我该如何修复它

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.WindowConstants;

public class LineExample {

    Color colors[] = new Color[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN,
            Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW };
    String colorNames[] = new String[] { "Black", "Blue", "Cyan", "Dark Gray", "Gray", "Green", "Light Gray", "Magenta",
            "Orange", "Pink", "Red", "White", "Yellow" };
    HashMap<String, Color> hashMap = new HashMap<String, Color>();
    Color currentColor = colors[2];

    public LineExample() {

        fillHashMap(hashMap);

        JFrame frame = new JFrame();

        JPanel mainPanel = new JPanel(new BorderLayout());
        JPanel northPanel = new JPanel(new FlowLayout());
        JPanel centerPanel = new JPanel(new GridLayout(1, 2));
        CustomPanel customPanel = new CustomPanel();
        BluePanel bluePanel = new BluePanel();

        JComboBox<String> comboBox = new JComboBox<String>();
        addItems(comboBox);
        comboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                currentColor = hashMap.get(comboBox.getSelectedItem());
                centerPanel.repaint();
            }
        });

        JToggleButton toggleButton = new JToggleButton("Switch");
        toggleButton.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                centerPanel.removeAll();
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    centerPanel.add(bluePanel);
                    centerPanel.add(customPanel);
                } else if (e.getStateChange() == ItemEvent.DESELECTED) {
                    centerPanel.add(customPanel);
                    centerPanel.add(bluePanel);
                }
                centerPanel.revalidate();
                centerPanel.repaint();
            }
        });

        northPanel.add(comboBox);
        northPanel.add(toggleButton);
        centerPanel.add(customPanel);
        centerPanel.add(bluePanel);
        mainPanel.add(northPanel, BorderLayout.NORTH);
        mainPanel.add(centerPanel, BorderLayout.CENTER);

        frame.setContentPane(mainPanel);

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(250, 250);
        frame.setVisible(true);

    }

    public void addItems(JComboBox<String> comboBox) {
        for (int i = 0; i < colors.length; i++) {
            comboBox.addItem(colorNames[i]);
        }
        comboBox.setSelectedIndex(2);
    }

    public void fillHashMap(HashMap<String, Color> hashmap) {
        for (int i = 0; i < colors.length; i++) {
            hashMap.put(colorNames[i], colors[i]);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new LineExample();
            }
        });
    }

    public class BluePanel extends JPanel {
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            int width = 100;
            int height = 100;
            int x = ((this.getWidth() - width) / 2);
            int y = ((this.getHeight() - height) / 2);
            g.setColor(Color.BLUE);
            g.fillRect(x, y, width, height);
            g.setColor(Color.BLACK);
            g.drawRect(x, y, width, height);
        }
    }

    public class CustomPanel extends JPanel {
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            int width = 100;
            int height = 100;
            int x = ((this.getWidth() - width) / 2);
            int y = ((this.getHeight() - height) / 2);
            g.setColor(currentColor);
            g.fillRect(x, y, width, height);
            g.setColor(Color.BLACK);
            g.drawRect(x, y, width, height);
        }
    }

}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.FlowLayout;
导入java.awt.Graphics;
导入java.awt.GridLayout;
导入java.awt.event.ItemEvent;
导入java.awt.event.ItemListener;
导入java.util.HashMap;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JToggleButton;
导入javax.swing.WindowConstants;
公共类行示例{
颜色[]=新颜色[]{Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,Color.GRAY,Color.GREEN,
Color.LIGHT_GRAY、Color.洋红、Color.ORANGE、Color.PINK、Color.RED、Color.WHITE、Color.YELLOW};
字符串颜色名称[]=新字符串[]{“黑色”、“蓝色”、“青色”、“深灰色”、“灰色”、“绿色”、“浅灰色”、“洋红”,
“橙色”、“粉色”、“红色”、“白色”、“黄色”};
HashMap HashMap=新的HashMap();
颜色currentColor=颜色[2];
公共线路示例(){
fillHashMap(hashMap);
JFrame=新JFrame();
JPanel mainPanel=newjpanel(newborderlayout());
JPanel-northPanel=newjpanel(newflowlayout());
JPanel中心面板=新JPanel(新网格布局(1,2));
CustomPanel CustomPanel=新的CustomPanel();
BluePanel BluePanel=新的BluePanel();
JComboBox comboBox=新的JComboBox();
附加项(组合框);
comboBox.addItemListener(新的ItemListener(){
@凌驾
公共无效itemStateChanged(ItemEvent e){
currentColor=hashMap.get(comboBox.getSelectedItem());
centerPanel.repaint();
}
});
JToggleButton toggleButton=新的JToggleButton(“开关”);
toggleButton.addItemListener(新的ItemListener(){
@凌驾
公共无效itemStateChanged(ItemEvent e){
centerPanel.removeAll();
如果(如getStateChange()==ItemEvent.SELECTED){
添加(蓝色面板);
添加(自定义面板);
}else if(例如getStateChange()==ItemEvent.DESELECTED){
添加(自定义面板);
添加(蓝色面板);
}
centerPanel.revalidate();
centerPanel.repaint();
}
});
添加(组合框);
添加(切换按钮);
添加(自定义面板);
添加(蓝色面板);
添加(northPanel,BorderLayout.NORTH);
主面板。添加(中心面板、边框布局。中心);
frame.setContentPane(主面板);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
框架。设置尺寸(250250);
frame.setVisible(true);
}
公共无效附加项(JComboBox组合框){
for(int i=0;i
可能与什么有关?当我面对这些问题时,我通常会做一些事情,比如

Graphics2D g2 = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

// draw stuff

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);

这是一个有趣的问题,因为LCD显示器中的亚像素排列。我用手机拍了一些显示器的照片来解释这种效果

首先我们看左边。这条线看起来大约有2像素厚。这是因为在直线上从左向右是一个从黑到蓝的过渡。由于红色和绿色像素不能为蓝色点亮,我们必须等到线条结束后的下一个蓝色亚像素

然后我们看右边。这条线是ap
Graphics2D g2 = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

// draw stuff

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);