你如何在另一个上面绘制JPanel?

时间:2018-03-26 08:40:59

标签: java swing jpanel

所以我有2个JPanels,StopWatchDial,它们基本上只是带有构造函数的圆圈(topleftX,topleftY,直径,最后一个参数不影响尺寸)。我试图拥有它,所以有一个大的外圆绘制,内部绘制一个较小的内圆,但我有问题。我假设这个过程很简单,只是覆盖了paintComponent方法,但我只是忽略了什么?

import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Stopwatch extends JPanel
{
    private StopWatchDial innerDial;
    private StopWatchDial outerDial;
    public Stopwatch(int x1, int y1, int width1, int x2, int y2, int width2)
    {
        innerDial = new StopWatchDial(x1, y1, width1, 60);
        outerDial = new StopWatchDial(x2, y2, width2, 1);
        this.add(outerDial);
        this.add(innerDial);
    }
    public void paintComponent(Graphics g)
    {
        outerDial.paintComponents(g);
        innerDial.paintComponents(g);
    }
    public static void main(String[] args) 
    {
        JFrame starter = new JFrame("test");
        starter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Stopwatch test = new Stopwatch( 150, 20, 300, 0, 0, 600);
        starter.add(test);
        starter.setSize(1000, 1000);
        starter.setVisible(true);
    }
}

我目前遇到的问题不是在彼此之上创建,而是产生这个:

https://i.imgur.com/RGZbGtq.png

2 个答案:

答案 0 :(得分:0)

当StopWatchDial是一个组件时,可以使用JLayeredPane堆叠它们。

public class Stopwatch extends JLayeredPane
{
    private StopWatchDial innerDial;
    private StopWatchDial outerDial;
    public Stopwatch(int x1, int y1, int width1, int x2, int y2, int width2)
    {
        innerDial = new StopWatchDial(x1, y1, width1, 60);
        outerDial = new StopWatchDial(x2, y2, width2, 1);
        add(outerDial, JLayeredPane.DEFAULT_LAYER);
        add(innerDial, Integer.valueOf(10));
    }

    public static void main(String[] args) 
    {
        final JFrame starter = new JFrame("test");
        starter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Stopwatch test = new Stopwatch( 150, 20, 300, 0, 0, 600);
        starter.add(test);
        starter.setSize(1000, 1000);
        starter.pack(); // Could be used to do optimal layouting.
        EventQueue.invokeLater(() -> starter.setVisible(true));
    }
}

答案 1 :(得分:0)

  

我目前所拥有的问题不是相互创建而是产生这个问题:

默认情况下,JPanel使用FlowLayout。所以你的秒表面板使用FlowLayout。向面板添加两个组件时,它们将显示在一行中。

如果您希望组件在彼此之上(使用Z轴),则需要:

  1. 使用innerDial.setOpaque(false)使顶部面板不透明。
  2. 使用在Z轴上显示组件的布局管理器,如OverlayLayout。我认为您需要将alignmentX / Y值设置为0.5f,以确保组件彼此居中。 Swing以与添加到面板相反的顺序绘制组件,因此您将innerDial和outerDial添加到秒表面板,因此outerDial会在innerDial之前绘制。
  3. 以上答案仅供参考。它不应该是你的最终解决方案。拥有3个组件并不是最好的设计方法。您应该只创建一个Stopwatch组件,这样程序员每次想要使用该组件时都不必处理布局问题。

      

    我认为这个过程很简单,只需要覆盖paintComponent方法,

    paintComponent()方法用于绘制组件的Graphics。它不用于绘制其他组件。您不应该在另一个组件上调用paintComponents()。

    因此,您可以将所有绘制代码​​添加到StopWatch类的paintComponent(...)方法中,而不是使用3个组件。这将是一个更好的设计,因为与显示秒表相关的所有逻辑都在一个类中,并且不依赖于以适当的布局添加到秒表的其他类。

    阅读Custom Painting上Swing教程中的部分,了解更多信息和示例。