【问题标题】:How to create a custom border class that modifies an existing border如何创建修改现有边框的自定义边框类
【发布时间】:2013-11-12 02:28:17
【问题描述】:

我正在开发一个用于桌面 RPG 的图形工具,该工具将显示一个网格并允许用户更改网格的线条(即边框) - 其中网格的每个正方形都是一个 jpanel - 单击鼠标。

我目前拥有的代码如下:

if(quadrant ==2)
{
      setBorder(new CompoundBorder(getBorder(), new MatteBorder(0,0,3,0, Color.BLUE)));
}

如果在正方形底部附近的点范围内单击鼠标,底部边框将变为蓝色,而其他边框将保持不变。此代码不起作用,因为它将新边框添加到旧边框。在随后点击底线时,蓝色边框会变高,因为新的蓝色边框会放在前一个蓝色边框的顶部......直到正方形被填充为蓝色。最终目标是多次单击以循环显示颜色 - 即单击一次蓝色,单击两次绿色,单击三下将其恢复为默认黑色。

我的想法是创建一个新的自定义边框类,它采用 getBorder(),但对其进行了修改,使一侧没有边框。但我不知道如何去做。

编辑添加完整代码:

TestGrid02 类:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class TestGrid02 {

public static void main(String[] args) {
    new TestGrid02();
}

public TestGrid02() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });
}
}

TestPane 类:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

 public class TestPane extends JPanel {
    Border border = null;
    public TestPane() {
        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        for (int row = 0; row < 10; row++) {
            for (int col = 0; col < 10; col++) {
                gbc.gridx = col;
                gbc.gridy = row;

                CellPane cellPane = new CellPane();


                if (row < 9) {
                    if (col < 9) {
                        border = new MatteBorder(1, 1, 0, 0, Color.BLACK);
                    } else {
                        border = new MatteBorder(1, 1, 0, 1, Color.BLACK);
                    }
                } else {
                    if (col < 9) {
                        border = new MatteBorder(1, 1, 1, 0, Color.BLACK);
                    } else {
                        border = new MatteBorder(1, 1, 1, 1, Color.BLACK);
                    }
                }

                cellPane.setBorder(border);
                cellPane.setBackground(Color.WHITE);
                add(cellPane, gbc);
            }
        }
    }
}

CellPane 类:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;

public class CellPane extends JPanel {


    public CellPane() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                Point p = e.getPoint();
                int quadrant = 0;
                if((p.x >= 0 && p.x <11) && p.y >= 0 && p.y < 41)
                {
                    quadrant = 1;
                }
                else if((p.x >= 0 && p.x <41) && p.y >= 40)
                {
                    quadrant = 2;
                }
                else if((p.x >= 10 && p.x <51) && p.y < 11)
                {
                 quadrant = 3;   
                }
                else if((p.x >40 && p.y >10))
                {
                    quadrant = 4;
                }
                else
                {
                    quadrant = 5;
                }


                if(e.getButton()== MouseEvent.BUTTON1)
                {
                if(quadrant==1)
                {
                    Border border = getBorder();
                    if (border instanceof CompoundBorder) { 
                    border = ((CompoundBorder)border).getOutsideBorder();
                    }
                    setBorder(new CompoundBorder(border, new MatteBorder(0,3,0,0, Color.BLUE)));
                }
                if(quadrant ==2)
                {
                    Border border = getBorder();
                    if (border instanceof CompoundBorder) { 
                    border = ((CompoundBorder)border).getOutsideBorder();
                    }
                    setBorder(new CompoundBorder(border, new MatteBorder(0,0,3,0, Color.BLUE)));
                }
                if(quadrant ==3)
                {
                    Border border = getBorder();
                    if (border instanceof CompoundBorder) { 
                    border = ((CompoundBorder)border).getOutsideBorder();
                    }
                    setBorder(new CompoundBorder(border, new MatteBorder(3,0,0,0, Color.BLUE)));
                }
                if(quadrant == 4)
                {
                    Border border = getBorder();
                    if (border instanceof CompoundBorder) { 
                    border = ((CompoundBorder)border).getOutsideBorder();
                    }
                    setBorder(new CompoundBorder(border, new MatteBorder(0,0,0,3, Color.BLUE)));
                }


                //original code. These borders "grow" on subsequent clicks
                /*
                if(quadrant==1)
                {

                    setBorder(new CompoundBorder(getBorder(), new MatteBorder(0,3,0,0, Color.BLUE)));
                }
                if(quadrant ==2)
                {

                    setBorder(new CompoundBorder(getBorder(), new MatteBorder(0,0,3,0, Color.BLUE)));
                }
                if(quadrant ==3)
                {

                    setBorder(new CompoundBorder(getBorder(), new MatteBorder(3,0,0,0, Color.BLUE)));
                }
                if(quadrant == 4)
                {

                    setBorder(new CompoundBorder(getBorder(), new MatteBorder(0,0,0,3, Color.BLUE)));
                }
                */

                if(quadrant == 5)
                {
                    //setBorder(new MatteBorder(3,3,3,3, Color.BLUE));      //Click in the middle to highlight all sides of a square
                }



                }                                       
                }


        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(50, 50);
    }
}

【问题讨论】:

    标签: java swing border


    【解决方案1】:

    基本上,您需要检查Border 并确定它是什么类型并从中做出选择...

    Border border = getBorder();
    if (border instanceof CompoundBorder) { 
        border = ((CompoundBorder)border).getOutsideBorder();
    }
    setBorder(new CompoundBorder(border, new MatteBorder(0,0,3,0, Color.BLUE)));
    

    基本上,这会检查border 是否已经是CompoundBorder,如果是则抓取外部边框。然后它使用现有的外部Border 和新的MatteBorder 创建一个新边框...

    这不是没有问题...

    根据问题的变化更新

    基本上,您需要某种方法来“记住”点击前的状态并保持那些不会改变的状态。

    基本上,我所做的是使用Insets。当用户点击时,我检查quadrant并相应地修改insets,然后更新Border

    public class CellPane extends JPanel {
    
        private Insets insets = new Insets(0, 0, 0, 0);
    
        public CellPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    Point p = e.getPoint();
                    int quadrant = 0;
                    if ((p.x >= 0 && p.x < 11) && p.y >= 0 && p.y < 41) {
                        quadrant = 1;
                    } else if ((p.x >= 0 && p.x < 41) && p.y >= 40) {
                        quadrant = 2;
                    } else if ((p.x >= 10 && p.x < 51) && p.y < 11) {
                        quadrant = 3;
                    } else if ((p.x > 40 && p.y > 10)) {
                        quadrant = 4;
                    } else {
                        quadrant = 5;
                    }
    
                    if (e.getButton() == MouseEvent.BUTTON1) {
                        if (quadrant == 1) {
                            System.out.println("Left");
                            insets.left = insets.left == 0 ? 3 : 0;
                        }
                        if (quadrant == 2) {
                            System.out.println("Bottom");
                            insets.bottom = insets.bottom == 0 ? 3 : 0;
                        }
                        if (quadrant == 3) {
                            System.out.println("Top");
                            insets.top = insets.top == 0 ? 3 : 0;
                        }
                        if (quadrant == 4) {
                            System.out.println("Right");
                            insets.right = insets.right == 0 ? 3 : 0;
                        }
    
                        Border border = getBorder();
                        if (border instanceof CompoundBorder) {
                            border = ((CompoundBorder) border).getOutsideBorder();
                        }
                        setBorder(new CompoundBorder(border, new MatteBorder(insets, Color.BLUE)));
    
                        if (quadrant == 5) {
                            //setBorder(new MatteBorder(3,3,3,3, Color.BLUE));      //Click in the middle to highlight all sides of a square
                        }
    
                    }
                }
    
            });
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50, 50);
        }
    }
    

    【讨论】:

    • 这确实解决了多次点击会导致新边框建立在旧边框之上的问题......但不适用于我正在尝试做的事情,因为点击其他区域正方形将导致第一个单击的区域恢复为我的默认边框(即,如果我单击左边框,然后顶部,左边框变回黑色。我需要它保持蓝色)。
    • 您需要提供一个可运行的示例,然后我才能接近理解所有内容:P
    • 我已经用完整的代码编辑了我的原始帖子。有趣的是,我刚刚注意到我正在处理的代码来自您今年早些时候回答的一个问题! :P (stackoverflow.com/questions/15421708/…)
    • 完美,看起来插图是我需要弄清楚的。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多