Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java swing/awt中的像素完美图形_Java_Swing_Awt_Graphics2d - Fatal编程技术网

Java swing/awt中的像素完美图形

Java swing/awt中的像素完美图形,java,swing,awt,graphics2d,Java,Swing,Awt,Graphics2d,有没有办法在Swing/AWT组件中实现像素完美的图形 我通过扩展AbstractBorder实现了按钮的自定义边框。出于演示目的,厚度始终等于3,并且每条线使用不同的颜色绘制 import javax.swing.*; import javax.swing.border.AbstractBorder; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicLookAndFeel; import java.awt

有没有办法在Swing/AWT组件中实现像素完美的图形

我通过扩展
AbstractBorder
实现了按钮的自定义边框。出于演示目的,厚度始终等于3,并且每条线使用不同的颜色绘制

import javax.swing.*;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicLookAndFeel;
import java.awt.*;

public class ExampleFrame extends JFrame {

    public ExampleFrame() {
        init();
    }

    public static void main(String[] args) throws UnsupportedLookAndFeelException 
    {
        UIManager.setLookAndFeel(new CustomLookAndFeel());

        ExampleFrame frame = new ExampleFrame();
        frame.setVisible(true);
    }

    private void init() {
        setLayout(new BorderLayout());

        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        getContentPane().add(panel, BorderLayout.NORTH);

        GridBagConstraints constraints = new GridBagConstraints();

        JButton button1 = new JButton("aaa");
        button1.setVerticalTextPosition(JButton.BOTTOM);
        button1.setHorizontalTextPosition(JButton.CENTER);
        button1.setFocusable(false);

        constraints.insets = new Insets(2, 2, 2, 2);
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.gridwidth = 1;
        constraints.gridheight = 3;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.anchor = GridBagConstraints.LINE_START;
        panel.add(button1, constraints);

        JButton button2 = new JButton("bbb");
        button2.setHorizontalAlignment(JButton.CENTER);
        button2.setFocusable(false);

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.gridwidth = 1;
        constraints.gridheight = 1;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.anchor = GridBagConstraints.LINE_START;
        panel.add(button2, constraints);

        JButton button3 = new JButton("eee");
        button3.setHorizontalAlignment(JButton.CENTER);
        button3.setFocusable(false);

        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.gridwidth = 1;
        constraints.gridheight = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.anchor = GridBagConstraints.LINE_START;
        panel.add(button3, constraints);

        JButton button4 = new JButton("ddd");
        button4.setHorizontalAlignment(JButton.CENTER);
        button4.setFocusable(false);

        constraints.gridx = 1;
        constraints.gridy = 2;
        constraints.gridwidth = 1;
        constraints.gridheight = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.anchor = GridBagConstraints.LINE_START;
        panel.add(button4, constraints);

        pack();
    }

    private static final class CustomBorder extends AbstractBorder {

        private final int thickness;

        public CustomBorder() {
            this(1);
        }

        public CustomBorder(int thickness) {
            this.thickness = thickness;
        }

        @Override
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
            //            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
            ((Graphics2D) g).setStroke(new BasicStroke(1.0f));

            for (int i = 0; i < thickness; i++) {
                switch (i) {
                    case 0: {
                        g.setColor(Color.RED);
                    }
                    break;
                    case 1: {
                        g.setColor(Color.GREEN);
                    }
                    break;
                    case 2: {
                        g.setColor(Color.BLUE);
                    }
                    break;
                }

                // top-left -> top-right
                g.drawLine(x, y + i, x + width, y + i);
                // top-left > bottom-left
                g.drawLine(x + i, y, x + i, y + height);
            }
        }

        @Override
        public Insets getBorderInsets(Component c, Insets insets) {
            insets.top = thickness;
            insets.bottom = thickness;
            insets.left = thickness;
            insets.right = thickness;
            return insets;
        }
    }

    private static final class CustomLookAndFeel extends BasicLookAndFeel {

        @Override
        protected void initComponentDefaults(UIDefaults table) {
            super.initComponentDefaults(table);

            // button
            Border buttonBorder = new CustomBorder(3);
            table.put("Button.border", buttonBorder);
            table.put("Button.background", new Color(150, 150, 182));
            table.put("Button.foreground", Color.BLACK);
        }

        @Override
        public String getName() {
            return "custom";
        }

        @Override
        public String getID() {
            return "custom";
        }

        @Override
        public String getDescription() {
            return "custom";
        }

        @Override
        public boolean isNativeLookAndFeel() {
            return false;
        }

        @Override
        public boolean isSupportedLookAndFeel() {
            return true;
        }
    }
}
import javax.swing.*;
导入javax.swing.border.AbstractBorder;
导入javax.swing.border.border;
导入javax.swing.plaf.basic.BasicLookAndFeel;
导入java.awt.*;
公共类ExampleFrame扩展了JFrame{
公共示例框架(){
init();
}
公共静态void main(字符串[]args)抛出不受支持的LookandFeelException
{
setLookAndFeel(新的CustomLookAndFeel());
ExampleFrame=新的ExampleFrame();
frame.setVisible(true);
}
私有void init(){
setLayout(新的BorderLayout());
JPanel面板=新的JPanel();
panel.setLayout(新的GridBagLayout());
getContentPane().add(面板,BorderLayout.NORTH);
GridBagConstraints=新的GridBagConstraints();
JButton button1=新JButton(“aaa”);
按钮1.设置垂直文本位置(JButton.底部);
按钮1.设置水平文本位置(JButton.CENTER);
按钮1.设置聚焦(假);
constraints.insets=新的insets(2,2,2,2);
constraints.gridx=0;
constraints.gridy=0;
constraints.gridwidth=1;
约束条件:网格高度=3;
constraints.fill=gridbagsconstraints.BOTH;
constraints.anchor=gridbagsconstraints.LINE\u START;
面板.添加(按钮1,约束);
JButton button2=新JButton(“bbb”);
按钮2.设置水平对齐(按钮中心);
按钮2.设置聚焦(假);
constraints.gridx=1;
constraints.gridy=0;
constraints.gridwidth=1;
约束条件。网格高度=1;
constraints.fill=gridbagsconstraints.BOTH;
constraints.anchor=gridbagsconstraints.LINE\u START;
面板。添加(按钮2,约束);
JButton button3=新JButton(“eee”);
按钮3.设置水平对齐(按钮中心);
按钮3.设置聚焦(假);
constraints.gridx=1;
constraints.gridy=1;
constraints.gridwidth=1;
约束条件。网格高度=1;
constraints.fill=gridbagsconstraints.HORIZONTAL;
constraints.anchor=gridbagsconstraints.LINE\u START;
面板.添加(按钮3,约束);
JButton button4=新JButton(“ddd”);
按钮4.设置水平对齐(JButton.CENTER);
按钮4.设置聚焦(假);
constraints.gridx=1;
constraints.gridy=2;
constraints.gridwidth=1;
约束条件。网格高度=1;
constraints.fill=gridbagsconstraints.HORIZONTAL;
constraints.anchor=gridbagsconstraints.LINE\u START;
面板。添加(按钮4,约束);
包装();
}
私有静态最终类CustomBorder扩展了AbstractBorder{
最终厚度;
公共边界(){
这(1);
}
公共自定义边框(整数厚度){
这个。厚度=厚度;
}
@凌驾
公共空白画框(组件c、图形g、整数x、整数y、整数宽度、整数高度){
((Graphics2D)g).setRenderingHint(renderingHits.KEY\u STROKE\u控件,renderingHits.VALUE\u STROKE\u PURE);
//((Graphics2D)g).setRenderingHint(renderingHits.KEY\u STROKE\u控件,renderingHits.VALUE\u STROKE\u NORMALIZE);
(图2d)g.设定行程(新基本行程(1.0f));
对于(int i=0;i右上
g、 抽绳(x,y+i,x+宽度,y+i);
//左上>左下
g、 抽绳(x+i,y,x+i,y+高度);
}
}
@凌驾
公共插图getBorderInsets(组件c,插图插图插图){
插图顶部=厚度;
插图。底部=厚度;
插图左=厚度;
插图右=厚度;
返回插图;
}
}
私有静态最终类CustomLookAndFeel扩展了BasicLookAndFeel{
@凌驾
受保护的void initComponentDefaults(UIDefaults表){
super.initComponentDefault(表);
//钮扣
边框按钮顺序=新的自定义边框(3);
表.put(“按钮.边框”,按钮顺序);
表.put(“按钮.背景”,新颜色(150、150、182));
表.放置(“按钮.前景”,颜色.黑色);
}
@凌驾
公共字符串getName(){
返回“自定义”;
}
@凌驾
公共字符串getID(){
返回“自定义”;
}
@凌驾
公共字符串getDescription(){
返回“自定义”;
}
@凌驾
公共布尔值isNativeLookAndFeel(){
返回false;
}
@凌驾
公共布尔值isSupportedLookAndFeel(){
返回true;
}
}
}
即使所有3个按钮都有相同的边框参数,我也会显示不同的边框宽度和颜色

VALUE_STROKE_PURE和VALUE_STROKE_NORMALIZE提示给出不同的结果,但它们都不是像素精确的

右侧的按钮“bbb”、“eee”和“ddd”具有相同的宽度和高度,但边框的颜色和总宽度仍然不同。此外,诽谤