- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使 JLabels 和 textFields 显示在 JPanel 上时遇到一些问题。如果我将所有这些代码放在主方法中,它可以正常工作,但是当我将 JLabels 和 TextFields 移动到它们自己的方法或类中时,JPanel 仍然为空。显示了我使用的图像。
package gui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
@SuppressWarnings("serial")
class ImagePanel extends JPanel {
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
}
}
public class EquippedInput {
private JPanel panel;
public static void main(String[] args){
ImagePanel panel = new ImagePanel(new ImageIcon("Images/Crusader Background.jpg").getImage());
JScrollPane scrollBar = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.setLayout(null);
JFrame frame = new JFrame();
frame.getContentPane().add(scrollBar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1160, 1000);
frame.setVisible(true);
panel.setPreferredSize(new Dimension(1125, 1210));
scrollBar.getVerticalScrollBar().setUnitIncrement(20);
}
public EquippedInput() {
initialize();
}
private void initialize() {
/**
* Stats and slots labels.
*/
JLabel lblWeaponAttacksPerSecond = new JLabel("Weapon Attacks Per Second");
JLabel lblWeaponAttackSpeed = new JLabel("Attack Speed");
JLabel lblMainHand = new JLabel("Main Hand");
JLabel lblOffHand = new JLabel("Off Hand");
JLabel stats[] = {lblWeaponAttacksPerSecond, lblWeaponAttackSpeed};
JLabel slots[] = {lblMainHand, lblOffHand};
/**
* Place stats and slots labels.
*/
for (int i = 0; i < stats.length; i++) {
stats[i].setBounds(10, (40 + 30 * i), 200, 20);
panel.add(stats[i]);
}
for (int i = 0; i < slots.length; i++) {
slots[i].setBounds((220 + 70 * i), 10, 60, 20);
panel.add(slots[i]);
}
/**
* Text fields.
*/
JTextField textField0 = new JTextField();
JTextField textField1 = new JTextField();
JTextField mainHandTextField[] = {textField0, textField1};
/**
* Arrays of whether a stat can roll on an item. 1 = can roll. 0 = can't roll.
*/
int mainHandAvailableStats[] = {0, 1};
/**
* Text field builders, each loop is a single slot.
*/
for (int i = 0; i < mainHandTextField.length; i++) {
panel.add(mainHandTextField[i]);
if(mainHandAvailableStats[i] == 1) {
int textFieldVerticalPosition = 40 + 30 * i;
mainHandTextField[i].setBounds(220, textFieldVerticalPosition, 60, 20);
panel.add(mainHandTextField[i]);
}
}
}
}
实际代码为 JPanel 提供了更多内容,但这会产生完全相同的结果。
最佳答案
稍后我将不得不解释此代码和此答案,但它显示:
数据文件是这样的:
Main_Hand Off_Hand Head Shoulder Neck
Weapon_Attacks_per_sec 5 null null null null
Attack_Speed 20 null null null null
Damage_% 30 null null null null
Min_Bonus_Damage 3 null null null null
Max_Bonus_Damage 40 null null null null
Min_Weapon_Damage 30 null null null null
Max_Weapon_Damage 80 null null null null
Strength 70 50 20 30 30
它必须命名为 TableFunData.txt
并且与代码位于同一目录/包中。
代码是:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Scanner;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
@SuppressWarnings("serial")
public class TableFun extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/d/d1/Ozanne-Brest.jpg";
private JTable table = new JTable();
private BufferedImage img;
public TableFun(BufferedImage img, TableModel model) {
this.img = img;
table = new JTable(model);
table.setDefaultRenderer(Object.class, new MyCellRenderer());
table.setOpaque(false);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setShowGrid(false);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
@Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
if (isPreferredSizeSet() || img == null) {
return superSize;
}
int supW = superSize.width;
int supH = superSize.height;
int imgW = img.getWidth();
int imgH = img.getHeight();
int w = Math.max(imgW, supW);
int h = Math.max(imgH, supH);
return new Dimension(w, h);
}
private class MyCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (column != 0) {
renderer.setHorizontalAlignment(JLabel.CENTER);
} else {
renderer.setHorizontalAlignment(JLabel.LEADING);
}
renderer.setOpaque(value != null);
return renderer;
}
}
private static void createAndShowGui() {
BufferedImage img = null;
try {
URL imageUrl = new URL(IMG_PATH);
img = ImageIO.read(imageUrl);
} catch (IOException e1) {
e1.printStackTrace();
System.exit(-1);
}
String dataPath = "TableFunData.txt";
DataIO dataIO = new DataIO(dataPath);
TableModel model = null;
try {
model = dataIO.createTableModel();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("Table Fun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TableFun(img, model));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class DataIO {
private static final String NULL = "null";
private String dataPath;
public DataIO(String dataPath) {
this.dataPath = dataPath;
}
public TableModel createTableModel() throws IOException {
InputStream inputStream = getClass().getResourceAsStream(dataPath);
Scanner scanner = new Scanner(inputStream);
Vector<String> columnNames = new Vector<>();
Vector<Vector<Object>> data = new Vector<>();
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (columnNames.size() == 0) {
columnNames = createColumnNames(line);
} else {
Vector<Object> dataRow = createDataRow(line);
data.add(dataRow);
}
}
if (scanner != null) {
scanner.close();
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
return model;
}
private Vector<String> createColumnNames(String line) {
String[] tokens = line.split("\\s+");
Vector<String> columnNames = new Vector<>();
columnNames.add(" "); // first name is blank
for (String token : tokens) {
if (!token.trim().isEmpty()) {
token = token.replace("_", " "); // add spaces
columnNames.add(token);
}
}
return columnNames;
}
private Vector<Object> createDataRow(String line) {
String[] tokens = line.split("\\s+");
Vector<Object> dataRow = new Vector<>();
for (String token : tokens) {
token = token.trim();
if (!token.isEmpty()) {
// first token is the title
if (dataRow.size() == 0) {
token = token.replace("_", " "); // add spaces
dataRow.add(token);
} else {
// if title already added
if (token.equalsIgnoreCase(NULL)) {
dataRow.add(null);
} else {
int value = Integer.parseInt(token);
dataRow.add(value);
}
}
}
}
return dataRow;
}
}
GUI 看起来像:
<小时/>现在进行一些解释:
好的,这段代码的作用是:
首先,我使用外部图像,该图像可以从 Wikipedia/Wikimedia 免费获取,以便我的代码可以从任何计算机运行并演示 JPanel 中图像的使用。图片路径可以在这里找到:
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/d/d1/Ozanne-Brest.jpg";
这里用它来创建图像:
URL imageUrl = new URL(IMG_PATH);
img = ImageIO.read(imageUrl);
然后在 JPanel 的 PaintComponent 方法中进行绘制:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
我的代码还扩展了 JPanel,因为这为我的 GUI 程序提供了比扩展 JFrame 更大的灵 active :
public class TableFun extends JPanel {
我重写 JPanel 的 getPreferredSize 方法,以便其大小适合图像,除非它需要更大。这就是为什么我首先获得 super 的首选尺寸,并尝试使我的 GUI 足够大以显示图像,如果需要显示更多组件则更大:
@Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
if (isPreferredSizeSet() || img == null) {
return superSize;
}
int supW = superSize.width;
int supH = superSize.height;
int imgW = img.getWidth();
int imgH = img.getHeight();
int w = Math.max(imgW, supW);
int h = Math.max(imgH, supH);
return new Dimension(w, h);
}
为了简化代码,我尝试将代码与数据分开,并将数据放在文本文件中。 DataIO 类是一个小型实用程序类,用于读取文件保存的文本,然后逐行解析数据以创建并填充 DefaultTableModel 对象。请注意,我获取的文件不是作为"file",而是作为类资源,因为这样,如果我愿意,我可以将其包含在 jar 文件中。我使用扫描仪读取每一行,就像读取文本文件一样。
public TableModel createTableModel() throws IOException {
InputStream inputStream = getClass().getResourceAsStream(dataPath);
Scanner scanner = new Scanner(inputStream);
一旦我得到一行文本,我就用空格分割它,这会创建一个字符串数组,所有空格都被修剪掉:
String[] tokens = line.split("\\s+");
JTable 使用名为 MyCellRenderer 的表格单元格渲染器
table.setDefaultRenderer(Object.class, new MyCellRenderer());
如果单元格包含数据,则单元格不透明;如果单元格包含空值,则单元格不透明(透明):
renderer.setOpaque(value != null);
我还确保 JTable 本身、JScrollPane 和滚动 Pane 的视口(viewport)都是非透明的,以便图像可以显示:
table.setOpaque(false);
// ....
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
<小时/>
您提到抛出了 NPE,这可能意味着您的 Java 程序找不到文本文件。同样,它必须与您的类文件放在一起。您应该使用 Eclipse 在与 java 文件相同的目录中创建一个文本文件,将其精确命名为 TableFunData.txt(拼写和大小写很重要),然后完成后,Eclipse 应该类似于:
使用 Eclipse 的包资源管理器可以在同一个包中看到代码和数据文本(以蓝色和红色突出显示),并且代码的包声明应该显示它实际上位于该包内(以绿色显示)。
关于java - 在单独的方法/类中声明时,JLabels 和 TextFields 不会出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37630082/
我正在开发转换器应用程序。在 iOS 中,我们没有下拉菜单之类的东西。对于一两次转换,这不是问题。但是对于相同类型的多次转换(比如时间:年到月、日、小时、分钟和秒),我们也有相反的转换。它使 UIVi
目前我的 SwiftUI 的光标/插入符号 TextField是蓝色的。是否有用于光标颜色或解决方法的 API? 最佳答案 试了一下, .accentColor 诀窍。 TextField(" Ent
我需要有关此功能的帮助。当我在文本字段中输入文本时,我需要您在我输入另一个文本字段时验证该文本。 这是我的代码 class _ProfileState extends State {
所以在 swift 3 中,我只想遍历 textField outlet 集合,如果 textField.text = "",则对其进行处理。我已经完成了以下操作,但我相信应该有一个更优雅的解决方案,
我正在尝试: 使 TextField 的 trailingIcon 仅在用户输入空格以外的文本时才可见。 稍后当用户单击 trailingIcon 时,TextField 中的文本应该被清除并且 tr
我目前正在尝试实现一个 TextField,它应该根据文本字段的状态(未聚焦、聚焦、错误)更改背景颜色。 我试图通过使用仅管理是否选择了 TextField 的列表来实现此目的。我使用 Gesture
我目前正在我的应用程序中构建一些基本的表单功能,并且在点击另一个 TextField 或在编辑模式下按“完成”时,我遇到了 TextFields 没有更改相关绑定(bind)变量中的值的问题。
我想要一个如下所示的文本字段: 文本字段。文本域 。文本域。文本字段 并在文本字段中仅输入数字。你能帮我吗? :) 最佳答案 您不需要父文本字段来充当 4 个文本字段的容器。将 4 个文本字段放置在面
你好,占位符文本和用户输入的文本从我的文本字段中间开始。我将文本字段设置为屏幕高度的 30%,所以我不能简单地缩小文本字段。如何让文本从左上角开始? 最佳答案 你想要做的是水平和垂直对齐,如下所示:
我遇到了一些奇怪的问题,如果您点击其中一个 TextField,它总是会被清除。 class MyEditText extends StatefulWidget { static String t
我在实现 TextField 时遇到了一些困难。更具体地说,我尝试使用 Controller 清除按钮的 onPress 方法上的 TextField。 controller.clear() 从 Te
有没有一种方法可以让当用户在一个文本字段和另一个文本字段(例如 1 和 1)中输入值时,第三个文本字段立即计算总和并显示它无需向 GUI 添加按钮? 最佳答案 向您的 TextField 添加一个文档
使用 ABCPDF 添加 TextField 相当简单: public FormField AddTextField(string inRect, string inName, string inTe
有两个文本字段(具有自动完成功能): Customer: Store: 如您所见,最初我禁用了第二个文本字段。我想要的是当用户完成从客户文本框中选择项目时,应该启用商店文本框。这是我尝试过
假设我有一个社交网络(例如: http://www.icloud.com/ )。该网站上有 2 个文本字段:电子邮件、密码。 我想为该网站制作一个应用程序,您可以直接从该应用程序登录。在应用程序上,我
在我的添加联系人页面中,正在验证我的电子邮件文本字段、电话号码字段等。并在单击所有其他文本字段时检查有效电子邮件。因此,当我单击电话号码字段时,它将检查电子邮件有效性并在电子邮件无效时显示警报 Vie
使用 TextField View 时,我的 SwiftUI 项目出现奇怪的行为。 使用以下代码,TextField textContentType 设置为 nil(或 .none,或 UITextC
我有一个 TextField 和一个 Text 小部件,它们应该实时显示在 TextField 中编写的文本。 这是代码: late final TextEditingController _imp
我有 2 个自动完成 UITextField这将在输入文本时触发表格 View 。其中一个我正在使用MVPlaceSearchTextField .我使用 this 自定义构建的另一个. 当我输入 t
我创建了一个函数,可以“映射”对象数组并使用该信息创建material-ui TextField 元素。当用户输入的字符超过 maxLength 时,我尝试输出错误消息。我想仅显示用户当前通过“onC
我是一名优秀的程序员,十分优秀!