Аналоговые часы работают, но секунды перерисовываются

Я сделал аналоговые часы, и они работают, но когда я удаляю заливку (фон), секундная стрелка продолжает повторяться, и когда я добавляю заливку, она работает. но я не хочу фон там. Спасибо

вот код

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Clock extends JPanel implements Runnable {

    Thread thread = null;
    SimpleDateFormat formatter = new SimpleDateFormat("s", Locale.getDefault());
    Date currentDate;
    int xcenter = 175, ycenter = 175, lastxs = 0, lastys = 0, lastxm = 0, lastym = 0, lastxh = 0, lastyh = 0;

    private void drawStructure(Graphics g) {
        g.setFont(new Font("TimesRoman", Font.BOLD, 20));
        g.setColor(Color.black);
//g.fillOval(xcenter - 150, ycenter - 150, 300, 300);
        g.setColor(Color.blue);
        g.setColor(Color.green);
        g.drawString("9", xcenter - 145, ycenter + 0);
        g.drawString("3", xcenter + 135, ycenter + 0);
        g.drawString("12", xcenter - 10, ycenter - 130);
        g.drawString("6", xcenter - 10, ycenter + 145);
    }

    public void paint(Graphics g) {
        int xhour, yhour, xminute, yminute, xsecond, ysecond, second, minute, hour;
        drawStructure(g);
        currentDate = new Date();
        formatter.applyPattern("s");
        second = Integer.parseInt(formatter.format(currentDate));
        formatter.applyPattern("m");
        minute = Integer.parseInt(formatter.format(currentDate));
        formatter.applyPattern("h");
        hour = Integer.parseInt(formatter.format(currentDate));
        xsecond = (int) (Math.cos(second * 3.14f / 30 - 3.14f / 2) * 120 + xcenter);
        ysecond = (int) (Math.sin(second * 3.14f / 30 - 3.14f / 2) * 120 + ycenter);
        xminute = (int) (Math.cos(minute * 3.14f / 30 - 3.14f / 2) * 100 + xcenter);
        yminute = (int) (Math.sin(minute * 3.14f / 30 - 3.14f / 2) * 100 + ycenter);
        xhour = (int) (Math.cos((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + xcenter);
        yhour = (int) (Math.sin((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + ycenter);
// Erase if necessary, and redraw
        g.drawLine(xcenter, ycenter, xsecond, ysecond);
        g.setColor(Color.red);
        g.drawLine(xcenter, ycenter - 1, xminute, yminute);
        g.drawLine(xcenter - 1, ycenter, xminute, yminute);
        g.setColor(Color.green);
        g.drawLine(xcenter, ycenter - 1, xhour, yhour);
        g.drawLine(xcenter - 1, ycenter, xhour, yhour);
        lastxs = xsecond;
        lastys = ysecond;
        lastxm = xminute;
        lastym = yminute;
        lastxh = xhour;
        lastyh = yhour;
    }

    public void start() {
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop() {
        thread = null;
    }

    public void run() {
        while (thread != null) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            repaint();
        }
        thread = null;
    }

    public void update(Graphics g) {
        paint(g);
    }

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        Color c = new Color(118, 73, 190);
        frame.setBackground(c);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0, 0, 400, 400);
        Clock clock = new Clock();
        frame.getContentPane().add(clock);
        frame.setVisible(true);
    }
}

person the King    schedule 06.10.2014    source источник
comment
Попробуйте перекрасить всю панель с помощью g.clearRect()   -  person ToasteR    schedule 06.10.2014


Ответы (1)


Вместо переопределения paint() программы Swing должны переопределять paintComponent(). Кроме того, вызовите super.paintComponent(), чтобы избежать такого рендеринга артефакт. Аналогичная проблема показана в этом связанном примере. Некоторые дополнительные наблюдения:

изображение

Как проверено:

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

//* @see https://stackoverflow.com/a/26213625/230513 */
public class Clock extends JPanel {

    private Timer t = new Timer(1000, (ActionEvent e) -> {
        repaint();
    });
    private SimpleDateFormat formatter = new SimpleDateFormat("s", Locale.getDefault());
    private Date currentDate;
    private int xcenter = 175, ycenter = 175, lastxs = 0, lastys = 0, lastxm = 0, lastym = 0, lastxh = 0, lastyh = 0;

    private void drawStructure(Graphics g) {
        g.setFont(new Font("TimesRoman", Font.BOLD, 20));
        g.drawString("9", xcenter - 145, ycenter + 0);
        g.drawString("3", xcenter + 135, ycenter + 0);
        g.drawString("12", xcenter - 10, ycenter - 130);
        g.drawString("6", xcenter - 10, ycenter + 145);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        int xhour, yhour, xminute, yminute, xsecond, ysecond, second, minute, hour;
        drawStructure(g);
        currentDate = new Date();
        formatter.applyPattern("s");
        second = Integer.parseInt(formatter.format(currentDate));
        formatter.applyPattern("m");
        minute = Integer.parseInt(formatter.format(currentDate));
        formatter.applyPattern("h");
        hour = Integer.parseInt(formatter.format(currentDate));
        xsecond = (int) (Math.cos(second * 3.14f / 30 - 3.14f / 2) * 120 + xcenter);
        ysecond = (int) (Math.sin(second * 3.14f / 30 - 3.14f / 2) * 120 + ycenter);
        xminute = (int) (Math.cos(minute * 3.14f / 30 - 3.14f / 2) * 100 + xcenter);
        yminute = (int) (Math.sin(minute * 3.14f / 30 - 3.14f / 2) * 100 + ycenter);
        xhour = (int) (Math.cos((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + xcenter);
        yhour = (int) (Math.sin((hour * 30 + minute / 2) * 3.14f / 180 - 3.14f / 2) * 80 + ycenter);
        g.drawLine(xcenter, ycenter, xsecond, ysecond);
        g.drawLine(xcenter, ycenter - 1, xminute, yminute);
        g.drawLine(xcenter - 1, ycenter, xminute, yminute);
        g.drawLine(xcenter, ycenter - 1, xhour, yhour);
        g.drawLine(xcenter - 1, ycenter, xhour, yhour);
        lastxs = xsecond;
        lastys = ysecond;
        lastxm = xminute;
        lastym = yminute;
        lastxh = xhour;
        lastyh = yhour;
    }

    public void start() {
        t.start();
    }

    public void stop() {
        t.stop();
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setBounds(0, 0, 400, 400);
            Clock clock = new Clock();
            frame.getContentPane().add(clock);
            frame.setVisible(true);
            clock.start();
        });
    }
}
person trashgod    schedule 06.10.2014
comment
Спасибо TrashGod, это работает, как я хотел. единственная проблема, с которой я столкнулся сейчас, это то, что я хочу создать jframe в netbeans и создать jpanel внутри него вручную, создать поток и использовать getGraphics(), но не работает, не могу передать код из-за пробела, но это часть его private void drawStructure(Graphics normal_g){ Graphics2D g = (Graphics2D) normal_g.create(); g = (Graphics2D) jptimer.getGraphics(); public void paintComponent (Graphics g) { g = (Graphics2D) jptimer.getGraphics (); } еще раз спасибо - person the King; 06.10.2014
comment
Вы можете использовать подход, показанный здесь. - person trashgod; 06.10.2014
comment
Спасибо, трэшбог, я многому научился из этого, кстати, я пытаюсь изменить стрелки (секунды, минуты, часы) на изображения, но я не понял, есть ли там, в любом случае, вы можете мне указать. еще раз спасибо - person the King; 08.10.2014
comment
См. embedded-resource и примеры, приведенные в информация. В дальнейшем вы можете принять этот ответ, щелкнув пустую галочку слева. - person trashgod; 08.10.2014