Java 每次帧更新JLabel';s面板已更新
如何在帧中的topPanel中将JLabelJava 每次帧更新JLabel';s面板已更新,java,swing,Java,Swing,如何在帧中的topPanel中将JLabelCount#0更新为Count#1(续) 最初它是Count#0,随着操作的进一步执行,它会变为Count#1 输出:它显示的是Count#0,但它应该是Count#2,因为灰色框位于第二级,同样,它应该显示Count#5,因为它位于顶部的第五级 import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; class Count { private
Count#0
更新为Count#1
(续)
最初它是Count#0
,随着操作的进一步执行,它会变为Count#1
输出:它显示的是Count#0
,但它应该是Count#2
,因为灰色框位于第二级,同样,它应该显示Count#5
,因为它位于顶部的第五级
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
class Count {
private int num;
public Count() {
this.num = 1;
}
// Generate Next Number
public void generate(int currentNumber) {
this.num = currentNumber;
this.num += 1;
}
public int getNumber() {
return this.num;
}
}
class Panel extends JPanel {
private final BufferedImage image;
private Count count;
public Panel() {
this.image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
this.count = new Count();
Timer timer = new Timer(0, ae -> createImage(image));
timer.setDelay(1000);
timer.start();
}
public void createImage(BufferedImage image) {
Graphics g = image.getGraphics();
int number = this.count.getNumber();
// Set field on frame which will be added to bottomPanel
for (int i = 0; i < (number * 20); i++) {
for (int j = 0; j < (number * 20); j++) {
g.setColor(Color.GRAY);
g.fillRect(i, j, 20, 20);
g.setColor(Color.GREEN);
g.drawRect(i, j, 20, 20);
}
}
// Generating next number
this.count.generate(number);
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}
class GUI extends JFrame {
private JPanel topPanel;
private JPanel bottomPanel;
public GUI() {
topPanel = new JPanel();
bottomPanel = new JPanel();
// Setting topPanel and Adding Label to topPanel
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.PAGE_AXIS));
updateLabel(0);
// Instructions for bottomPanel
Panel panel = new Panel();
panel.setPreferredSize(new Dimension(300, 300));
// Adding the instructions to bottomPanel
bottomPanel.add(panel);
// Adding topPanel and bottomPanel to Frame
add(topPanel, BorderLayout.PAGE_START);
add(bottomPanel, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
}
public void updateLabel(int number) {
// Label - 1
JLabel countLabel = new JLabel("CountLabel");
countLabel.setText(" Count #" + number);
countLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
countLabel.setBounds(10, 5, 300, 20);
topPanel.add(countLabel);
}
}
public class NumberPresentation {
public static void main(String[] args) {
new GUI().setVisible(true);
}
}
import java.awt.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
班级人数{
私有整数;
公众计数(){
this.num=1;
}
//生成下一个号码
公共void生成(int currentNumber){
this.num=当前编号;
这个.num+=1;
}
public int getNumber(){
返回这个.num;
}
}
类面板扩展了JPanel{
私有最终缓冲图像;
私人计数;
公共事务委员会(){
this.image=新的BuffereImage(300300,BuffereImage.TYPE_INT_RGB);
this.count=新计数();
定时器定时器=新定时器(0,ae->createImage(图像));
定时器设置延迟(1000);
timer.start();
}
public void createImage(buffereImage图像){
Graphics g=image.getGraphics();
int number=this.count.getNumber();
//在将添加到底部面板的框架上设置字段
对于(int i=0;i<(数字*20);i++){
对于(int j=0;j<(数字*20);j++){
g、 setColor(颜色为灰色);
g、 fillRect(i,j,20,20);
g、 setColor(Color.GREEN);
g、 drawRect(i,j,20,20);
}
}
//生成下一个数字
此.count.generate(number);
重新油漆();
}
公共组件(图形g){
超级组件(g);
g、 drawImage(image,0,0,null);
}
}
类GUI扩展了JFrame{
私人杰帕内尔·托帕内尔;
私人JPanel小组;
公共图形用户界面(){
topPanel=新的JPanel();
底部面板=新的JPanel();
//设置topPanel并向topPanel添加标签
topPanel.setLayout(新的BoxLayout(topPanel,BoxLayout.PAGE_轴));
更新标签(0);
//底部面板的说明
面板=新面板();
面板。设置首选尺寸(新尺寸(300300));
//将说明添加到底部面板
底部面板。添加(面板);
//将顶部面板和底部面板添加到框架
添加(topPanel,BorderLayout.PAGE_START);
添加(底部面板、边框布局、中间);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(空);
包装();
}
公共void updateLabel(整数){
//标签-1
JLabel countLabel=新JLabel(“countLabel”);
countLabel.setText(“Count#”+number);
countLabel.setFont(新字体(“Comic Sans MS”,Font.PLAIN,14));
countLabel.setBounds(10,5300,20);
topPanel.add(计数标签);
}
}
公共类编号表示{
公共静态void main(字符串[]args){
新建GUI().setVisible(true);
}
}
那么,我应该如何开始工作,以使topPanel中的JLabel在每次Count
classgenerate()
另一个数字时都保持更新,并且generate()
在面板中调用class的createImage()
函数
多谢各位
PS:底部面板动画很好,我只是想知道如何使用JLabel每次更新它。我建议采用面向回调的方法,这与JButton的addActionListener
的工作原理非常相似。警告:它有点长,如果您滥用它,可能会变得混乱,但它保持了初始类的完整分离
我们的想法是在面板类中添加一个onUpdate
方法,该方法在面板每次更新时都会被调用。然后定义创建面板时的操作
为此,您首先需要用所需的方法声明一个抽象类或接口,我选择泛型名称,但可以自由定制
接口回调{
公共无效诉讼(INTV);
}
现在,我们可以将declare和action方法传递给任何类,该方法接受一个整数,您只需添加一个回调字段:
类面板扩展了JPanel{
私有最终缓冲图像;
私人计数;
私有回调更新;
public void setOnUpdateAction(回调操作){
this.onUpdate=操作;
}
你可以自由选择在哪里拨打onUpdate,我是在下一个号码生成后拨打的
//生成下一个号码
此.count.generate(number);
onUpdate.action(this.count.getNumber());
重新油漆();
您的面板
类现在已准备就绪
现在,在创建面板之后,只需调用setOnUpdate操作
panel.setOnUpdateAction(新回调(){
公共无效诉讼(INTV){
countLabel.setText(“Count#”+v);
}
});
因为只有一个方法和一条指令,所以可以使用与计时器中使用的语法类似的更短的Lambda语法
panel.setOnUpdateAction(v->countLabel.setText(“Count#“+v));
(我必须将countLabel设置为一个字段,以便在GUI中访问它。)
就在这里
以下是完整的修改代码:
import java.awt.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
班级人数{
私有整数;
公众计数(){
this.num=1;
}
//生成下一个号码
公共void生成(int currentNumber){
this.num=当前编号;
这个.num+=1;
}
public int getNumber(){
返回这个.num;
}
}
接口回调{
公共无效诉讼(INTV);
}
P类