gpt4 book ai didi

java - 为什么我的自定义边框应用于所有组件?

转载 作者:搜寻专家 更新时间:2023-11-01 02:25:32 25 4
gpt4 key购买 nike

我正在尝试仅为面板创建一个仪表板边框(Java 7 之前的版本),但它也适用于面板中的所有组件。有谁知道为什么?

public class Box extends JPanel {

public Box() {
super();
DashedBorder dashedBorder = new DashedBorder();

this.setBorder(new TitledBorder(dashedBorder, "title", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION));
this.setLayout(new GridLayout(5, 1));
for (int i = 1; i <= 15; i++) {
this.add(new JCheckBox("" + i));
}

}


class DashedBorder extends AbstractBorder {
@Override
public void paintBorder(Component comp, Graphics g, int x, int y, int w, int h) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 5 }, 0));
g2d.drawRect(x, y, w - 1, h - 1);
}
}

public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
Box box = new Box();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setContentPane(p);
p.add(box,BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}



}

最佳答案

发生这种情况是因为您在绘制边框后没有清理图形设置。

基本上,Swing 使用与您收到的相同图形 paintBorder 方法用于绘制面板上的任何内容。因此,如果您设置笔触、合成、字体、颜色等 - 确保之后返回之前使用的设置,否则您可能会看到此类意外行为。

您无法预测在您之后绘制的组件是否会设置自己的笔划/合成/其他任何内容,因此您必须在完成绘制自己的东西后恢复默认图形设置。

好吧,实际上您可以跳过恢复颜色,因为几乎每个组件在绘制时都使用自己的颜色,因此保持默认值不变并不是那么重要。但是只有颜色,所有其他设置都应该恢复,除非你的组件没有任何子组件或者你 100% 确定子组件重新定义了一些特定的属性(我怀疑你无论如何都能确定)。

这里是简单的修复:

public class Box extends JPanel
{
public Box ()
{
super ();

DashedBorder dashedBorder = new DashedBorder ();
this.setBorder ( new TitledBorder ( dashedBorder, "title", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION ) );
this.setLayout ( new GridLayout ( 5, 1 ) );
for ( int i = 1; i <= 15; i++ )
{
this.add ( new JCheckBox ( "" + i ) );
}
}

class DashedBorder extends AbstractBorder
{
@Override
public void paintBorder ( Component comp, Graphics g, int x, int y, int w, int h )
{
Graphics2D g2d = ( Graphics2D ) g;
g2d.setColor ( Color.black );
final Stroke os = g2d.getStroke ();
g2d.setStroke ( new BasicStroke ( 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{ 5 }, 0 ) );
g2d.drawRect ( x, y, w - 1, h - 1 );
g2d.setStroke ( os );
}
}

public static void main ( String[] args )
{
JFrame frame = new JFrame ();
JPanel p = new JPanel ();
p.setLayout ( new BorderLayout () );
Box box = new Box ();
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.setSize ( 400, 400 );
frame.setContentPane ( p );
p.add ( box, BorderLayout.CENTER );
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
}
}

我怀疑是否有很多关于此的文章,因为没有多少人喜欢在类似容器的组件上进行绘画。如果您的组件是绘画“链”中的最后一个组件或基本上没有子组件,您将永远不会看到此问题。

在我自己的项目中,我使用一些分成一些实用程序类的辅助方法来帮助我进行设置/恢复操作,例如笔画:

public static Stroke setupStroke ( final Graphics2D g2d, final Stroke stroke )
{
return setupStroke ( g2d, stroke, true );
}

public static Stroke setupStroke ( final Graphics2D g2d, final Stroke stroke, final boolean shouldSetup )
{
if ( shouldSetup && stroke != null )
{
final Stroke old = g2d.getStroke ();
g2d.setStroke ( stroke );
return old;
}
else
{
return null;
}
}

public static void restoreStroke ( final Graphics2D g2d, final Stroke stroke )
{
restoreStroke ( g2d, stroke, true );
}

public static void restoreStroke ( final Graphics2D g2d, final Stroke stroke, final boolean shouldRestore )
{
if ( shouldRestore && stroke != null )
{
g2d.setStroke ( stroke );
}
}

所以你最终在绘画时只使用了两行代码:

final Stroke stroke = GraphicsUtils.setupStroke ( newStroke );

// paint something

GraphicsUtils.restoreStroke ( g2d, stroke );

关于java - 为什么我的自定义边框应用于所有组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24550104/

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