【问题标题】:Redrawing frame using JPanel使用 JPanel 重绘框架
【发布时间】:2015-07-08 23:20:02
【问题描述】:

我是java初学者;我最近从另一种编程语言转移,我只知道基础知识。
我在使用 JPanel 重绘时遇到问题。我可以在创建新对象时绘制文本,但在重绘它时遇到问题。函数 tick() 由 Main 类在短时间内调用,应该重绘 JPanel。

package main;

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Surface extends JPanel{
    private void doDrawing(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;
        g2d.drawString("Hello World! "+Main.integer, 50, 50);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        doDrawing(g);
    }
}
class Display extends JFrame {

    public Display() {
        Surface surface = new Surface();
        setTitle("salami");
        setSize(400, 300);
    }
    public void tick() {
        surface.redraw();
    }
}

【问题讨论】:

  • 我认为你应该 repaint() 或 revalidate() 组件
  • @HuangChen 我只解决了一部分问题。似乎“Surface surface = new Surface()”的工作方式不同于以前的“add(new Surface())”,它会导致“Hello World!”根本不画画。但是,当使用“add(new Surface())”创建表面时,我无法访问表面以供以后重新绘制。我该如何解决?
  • 我相信创建“Surface surface = new Surface()”会重新创建表面而不显示它。你的显示方法应该做它所说的“显示”,而不是你应该在其他地方创建表面并使其在 Display() 中可见
  • 什么是Main.integer?为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、独立、正确的示例)。
  • 顺便说一句 - 对于眼前的问题,请尝试将 public Display() { Surface surface = new Surface(); 更改为 Surface surface = new Surface(); public Display() { ;)

标签: java swing jframe jpanel java-2d


【解决方案1】:

实际上,您重绘了 JPanel。

这是我重绘的 JPanel 的最简单示例。这是一个每 200 毫秒重绘一次的时钟。

您首先创建 GUI,然后使用线程中的 Runnable 或 Swing Timer 定期更新 GUI。

这是代码。

package com.ggl.testing;

import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class SimpleClock implements Runnable {

    private JFrame frame;

    private JPanel panel;

    private JTextField clockDisplay;

    private Timer timer;

    @Override
    public void run() {
        frame = new JFrame("Clock");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                exitProcedure();
            }
        });

        createClockPanel();

        frame.add(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        timer = new Timer(this);
        new Thread(timer).start();
    }

    private void createClockPanel() {
        panel = new JPanel();
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 6));

        clockDisplay = new JTextField(12);
        clockDisplay.setEditable(false);
        clockDisplay.setHorizontalAlignment(JTextField.CENTER);

        panel.add(clockDisplay);
    }

    public void exitProcedure() {
        timer.setRunning(false);
        frame.dispose();
        System.exit(0);
    }

    public void setText(String text) {
        clockDisplay.setText(text);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleClock());
    }

    public class Timer implements Runnable {

        private volatile boolean running;

        private SimpleClock clock;

        private SimpleDateFormat timeFormat;

        public Timer(SimpleClock clock) {
            this.clock = clock;
            this.running = true;
            this.timeFormat = new SimpleDateFormat("h:mm:ss a");
        }

        @Override
        public void run() {
            while (running) {
                displayTime();
                sleep();
            }

        }

        public void displayTime() {
            final Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();
            final String s = timeFormat.format(date);
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    clock.setText(s);
                }
            });
        }

        public void sleep() {
            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
            }
        }

        public synchronized void setRunning(boolean running) {
            this.running = running;
        }

    }

}

【讨论】:

【解决方案2】:

您需要将您的extened JPanel 表面添加到您的JFrame

public Display() {
    Surface surface = new Surface();
    add(surface);
    setTitle("salami");
    setSize(400, 300);
}

如果这不起作用,请发布SSCCE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多