- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我在 Swing 方面遇到了一些问题。我正在创建一个需要在 JFrame 和 JPanel 中频繁编辑内容(在本例中为 JButton 上显示的字符串)的项目,我想了解如何执行此操作。
我搜索了很长时间,找到的主要答案是我需要调用 .repaint(),可能在调用 .revalidate() 之后。但是,我无法让我的代码正常运行。
现在,框架将按原样绘制,但按下按钮后,其中的文本不会改变 - 事实上,它会产生一个大错误日志,可在此处查看:https://pastebin.com/7P85cB8h
下面是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Actions extends JFrame implements ActionListener
{
JButton Beans;
String String1;
JPanel things;
public static void main (String[] args)
{
new Actions();
}
public Actions()
{
JPanel things = new JPanel();
String1 = "Beans";
this.setSize(400,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Hello there");
Box theBox = Box.createHorizontalBox();
Beans = new JButton("" + String1);
Beans.addActionListener(this);
theBox.add(Box.createHorizontalStrut(50));
theBox.add(Beans);
this.add(theBox);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
String1 = "Surprise!";
things.revalidate();
things.repaint();
}
}
所以,澄清一下,我有一个 JButton,在 JPanel 中,在 JFrame 中。该按钮本身显示一个字符串,最初显示为“Beans”。当我按下按钮时,我希望字符串现在显示为“Surprise!”。
感谢您的宝贵时间。
最佳答案
您的问题是将对象与引用变量混淆,认为更改 String1 的文本会神奇地导致 JButton 显示的文本发生变化,但这不是 Java 的 OOP 模型的工作方式。了解 JButton 正在显示一个 String 对象,String1 最初引用的是同一个对象,但是当您更改 String1 引用的 String 时,这对原始 String 对象没有影响。为了更改显示的字符串,您必须更改 JButton 显示的字符串对象,方法是调用 JButton 的 setText(...)
方法并将新的字符串传递给它。这是唯一可行的方法。
public void actionPerformed(ActionEvent e) {
Beans.setText("Surprise!");
}
查看评论:
// here are several reference variables
// all without assigned objects, and thus
// all holding "null" values:
JButton Beans;
String String1;
JPanel things;
public Actions() {
//.....
// here you assign the String object, "Beans" to the String1 variable
String1 = "Beans";
// .....
// here you create a JButton and pass in String1's current object, "Beans"
// into the constructor (note the "" + is NOT needed for Strings, only for numberrs)
Beans = new JButton("" + String1);
//.....
}
public void actionPerformed(ActionEvent e) {
// here you change the object that String1 refers to
String1 = "Surprise!";
// but this has no effect on the original String object, "Beans" displayed in the
// JButton, but rather all it does is change the state of String1.
// To change the state of the JButton, you must explicitly do this
// by calling setText on it
//....
顺便说一句,您需要学习和使用 Java naming conventions .变量名应全部以小写字母开头,而类名应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。
旁注 #2:如果您实际上绘制 字符串,那么您的原始代码就可以工作。请注意,在下面的代码中,我有一个字符串变量 currentString
,它最初指的是字符串数组 TEXTS
中的第一项,字符串 "One"
。在 JButton 的 ActionListener 中,我更新了名为 index
的数组索引变量,并将 currentString
变量设置为数组中的下一个 String 项,然后调用 repaint ()
。这段代码起作用的原因是因为我在 JPanel 的绘画方法 paintComponent(...)
中绘制由 currentString
保存的文本:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class DrawStringPanel extends JPanel {
private static final String[] TEXTS = {
"One", "Two", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Ten"
};
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 40);
private static final int TEXT_X = 150;
private static final int TEXT_Y = 200;
private int index = 0;
// Note that this String variable holds the first item in the TEXTS array
private String currentString = TEXTS[index];
public DrawStringPanel() {
setPreferredSize(new Dimension(PREF_W, PREF_H));
JButton nextBtn = new JButton("Next");
add(nextBtn);
nextBtn.addActionListener(e -> {
// update the array index
index++; // get next index
index %= TEXTS.length; // but don't let get bigger then array length
// and in the ActionListener here I'm changing the variable and calling repaint
// this works because this variable is actually painted within this JPanel's
// paintComponent method....
currentString = TEXTS[index];
repaint();
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(TEXT_FONT);
// ****** HERE ****** I draw the contents of the currentString variable
g2.drawString(currentString, TEXT_X, TEXT_Y);
}
private static void createAndShowGui() {
DrawStringPanel mainPanel = new DrawStringPanel();
JFrame frame = new JFrame("DrawStringPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
关于java - 通过 EventListener 调用 repaint() 和/或 revalidate() - Swing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52488908/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!