在面板上显示时钟

时间:2012-11-06 00:04:45

标签: java swing user-interface awt java-2d

由于某种原因,我将ClockComponent对象添加到JPanel对象时不会显示。当我将它添加到JFrame对象而不是JPanel对象时,它会显示出来......我不明白为什么我在这里发布这个问题之前已经查过了但是无济于事。有没有办法让我的ClockComponent对象继承自JComponent以显示在JPanel上?非常感谢你的帮助。

这是我的ClockViewer类,它在运行时不会显示时钟:

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

            public class ClockViewer
            {
                public static void main(String[] args)
                {
                    JFrame frame = new JFrame();
                    frame.setTitle("Clock viewer");
                    frame.setSize(500, 500);
                    JPanel panel = new JPanel();

                    ClockComponent comps = new ClockComponent(7, 40);

                    panel.add(comps);
                    frame.add(panel);

                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                }
            }

这是我的ClockComponent类供参考:

            import java.awt.Graphics;
            import java.awt.Graphics2D;
            import java.awt.geom.Ellipse2D;
            import java.awt.geom.Line2D;

            import javax.swing.JComponent;

            public class ClockComponent extends JComponent
            {
                final int CENTER = 150;
                final double HOUR_HAND_LENGTH = 20;
                final double MINUTE_HAND_LENGTH = 40;

                private Line2D.Double hourHand;
                private Line2D.Double minuteHand;

                public ClockComponent(double hour, double minute)
                {
                    hourHand = new Line2D.Double(CENTER, CENTER, 
                            CENTER, CENTER - HOUR_HAND_LENGTH);
                    minuteHand = new Line2D.Double(CENTER, CENTER, 
                            CENTER, CENTER - MINUTE_HAND_LENGTH);

                    final int HOURS_ON_CLOCK = 12;
                    final int MINUTES_IN_HOUR = 60;
                    final double HOURS_TO_RADIANS = 2 * Math.PI / HOURS_ON_CLOCK;
                    final double MINUTES_TO_RADIANS = 2 * Math.PI / MINUTES_IN_HOUR;

                    hourHand.setLine(CENTER, CENTER, CENTER + HOUR_HAND_LENGTH * 
                            Math.sin((hour + minute / MINUTES_IN_HOUR) * HOURS_TO_RADIANS), 
                            CENTER - HOUR_HAND_LENGTH * 
                            Math.cos((hour + minute / MINUTES_IN_HOUR) * HOURS_TO_RADIANS));
                    minuteHand.setLine(CENTER, CENTER,
                            CENTER + MINUTE_HAND_LENGTH * Math.sin(minute * MINUTES_TO_RADIANS),
                            CENTER - MINUTE_HAND_LENGTH * Math.cos(minute * MINUTES_TO_RADIANS));
                }

                public void paintComponent(Graphics g)
                {
                    final int DIAMETER = 100;
                    final int POS_X_Y = CENTER - DIAMETER / 2;

                    Graphics2D g2 = (Graphics2D) g;

                    Ellipse2D.Double clockFace = 
                            new Ellipse2D.Double(POS_X_Y, POS_X_Y, DIAMETER, DIAMETER);

                    g2.draw(clockFace);
                    g2.draw(hourHand);
                    g2.draw(minuteHand);
                }
            }

2 个答案:

答案 0 :(得分:3)

在面板中,您可以使用一种布局,使时钟组件填充面板的整个区域,例如GridLayout

JPanel panel = new JPanel(new GridLayout(1, 0));

面板的默认FlowLayout不会扩展任何子组件。

答案 1 :(得分:2)

ClockComponent应设置或覆盖首选大小。如果组件不可调整大小,许多人更喜欢覆盖它。这个例子只是设置它。

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class ClockComponent extends JComponent
{
    final int CENTER = 150;
    final double HOUR_HAND_LENGTH = 20;
    final double MINUTE_HAND_LENGTH = 40;

    private Line2D.Double hourHand;
    private Line2D.Double minuteHand;

    public ClockComponent(double hour, double minute)
    {
        setPreferredSize(new Dimension(300,300));
        hourHand = new Line2D.Double(CENTER, CENTER, 
                CENTER, CENTER - HOUR_HAND_LENGTH);
        minuteHand = new Line2D.Double(CENTER, CENTER, 
                CENTER, CENTER - MINUTE_HAND_LENGTH);

        final int HOURS_ON_CLOCK = 12;
        final int MINUTES_IN_HOUR = 60;
        final double HOURS_TO_RADIANS = 2 * Math.PI / HOURS_ON_CLOCK;
        final double MINUTES_TO_RADIANS = 2 * Math.PI / MINUTES_IN_HOUR;

        hourHand.setLine(CENTER, CENTER, CENTER + HOUR_HAND_LENGTH * 
                Math.sin((hour + minute / MINUTES_IN_HOUR) * HOURS_TO_RADIANS), 
                CENTER - HOUR_HAND_LENGTH * 
                Math.cos((hour + minute / MINUTES_IN_HOUR) * HOURS_TO_RADIANS));
        minuteHand.setLine(CENTER, CENTER,
                CENTER + MINUTE_HAND_LENGTH * Math.sin(minute * MINUTES_TO_RADIANS),
                CENTER - MINUTE_HAND_LENGTH * Math.cos(minute * MINUTES_TO_RADIANS));
    }

    public void paintComponent(Graphics g)
    {
        final int DIAMETER = 100;
        final int POS_X_Y = CENTER - DIAMETER / 2;

        Graphics2D g2 = (Graphics2D) g;

        Ellipse2D.Double clockFace = 
                new Ellipse2D.Double(POS_X_Y, POS_X_Y, DIAMETER, DIAMETER);

        g2.draw(clockFace);
        g2.draw(hourHand);
        g2.draw(minuteHand);
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setTitle("Clock viewer");
        // bad practice
        //frame.setSize(500, 500);
        JPanel panel = new JPanel();

        ClockComponent comps = new ClockComponent(7, 40);

        panel.add(comps);
        frame.add(panel);
        // Good practice.
        frame.pack();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}