【问题标题】:How can I customize a JDialog with round corners, no title, and no control buttons如何自定义带有圆角、无标题和无控制按钮的 JDialog
【发布时间】:2021-09-29 05:37:02
【问题描述】:

如何自定义带有圆角、没有标题和控制按钮的JDialog。就像下面的一样。

【问题讨论】:

  • 但是对话框不能像普通对话框那样拖动移动。怎么办? - 见:Moving Windows

标签: java swing


【解决方案1】:

就像生活中的大多数事情一样,这是一种幻觉。

你实际上是在问三个问题......

  1. 如何去除窗户装饰
  2. 如何使窗口透明
  3. 如何绘制“圆角”矩形

所有事情都相对容易做,知道你需要它们,这是另一个问题。

所以,对于前两个...

JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setBackground(new Color(0, 0, 0, 0));
dialog.setModal(true);
dialog.setSize(640, 480);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);

您需要移除窗口装饰并将背景设置为透明色。如果你运行上面的代码,你会发现,什么都没有,实际上有点令人毛骨悚然。那是因为窗户没有装饰,是透明的。

下一步将需要一个自定义组件。同样,这是一种错觉。我们要让组件透明,但是,我们要手动填充它。

public class RoundedPane extends JPanel {

    private int radius = 20;
    
    public RoundedPane() {
        setOpaque(false);
        setBorder(new EmptyBorder(10, 10, 10, 10));
        setLayout(new BorderLayout());
    }

    public void setRadius(int radius) {
        this.radius = radius;
        setBorder(new EmptyBorder(radius / 2, radius / 2, radius / 2, radius / 2));
        revalidate();
        repaint();
    }

    public int getRadius() {
        return radius;
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(getBackground());
        g2.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
        g2.setColor(getForeground());
        g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
        super.paintComponent(g);
    }
}

所以,简单地说,这将创建一个JPanel,使其透明(setOpaque(false)),然后覆盖它的paintComponent,这样我们就可以绘制圆形效果了。

现在,如果你把它放在一起,你最终会得到这样的东西......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JDialog dialog = new JDialog();
                dialog.setUndecorated(true);
                dialog.setBackground(new Color(0, 0, 0, 0));
                dialog.setModal(true);
                dialog.setContentPane(new RoundedPane());
                dialog.setSize(640, 480);
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);
            }
        });
    }

    public class RoundedPane extends JPanel {

        private int radius = 20;

        public RoundedPane() {
            setOpaque(false);
            setBorder(new EmptyBorder(10, 10, 10, 10));
            setLayout(new BorderLayout());
        }

        public void setRadius(int radius) {
            this.radius = radius;
            setBorder(new EmptyBorder(radius / 2, radius / 2, radius / 2, radius / 2));
            revalidate();
            repaint();
        }

        public int getRadius() {
            return radius;
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(getBackground());
            g2.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
            g2.setColor(getForeground());
            g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
            super.paintComponent(g);
        }
    }
}

所以,关于上述示例的一些即时说明。

  • 我特意在这个例子中使用了setSizeRoundedPane 应该根据Border 及其内容推迟计算所需的大小,所以我们不想修改它,但由于它会给出0x0 的首选大小,所以我设置了对话框的大小我。你应该依靠pack来获得更好的效果。
  • 我已将RoundedPane 设置为对话框的contentPane。这将允许您像往常一样继续将内容直接添加到对话框中。您可以直接向RoundedPane 添加内容,但这也可以确保现有的contentPane 不会干扰我们的工作。

你还应该看看:

这样我发现这个没有修饰所有字体类型的变化,我如何在整个对话框中设置字体类型。

字体由安装的外观管理。如果您确实对字体有问题,那么您做错了什么,这是一个特定于平台的问题(即错误)

【讨论】:

  • 但对话框不能像普通对话框一样拖动移动。怎么办?
  • 如果你删除了窗口装饰的功能,你需要接管那些责任 - for example
  • 这样我发现这个没有修饰所有字体类型的变化,我如何在整个对话框中设置字体类型。
  • 框架的装饰应该对字体样式没有影响,因为它由UIManager和安装的外观管理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
相关资源
最近更新 更多