无法在方法中使用 html 创建新的 JLabel
unable to create new JLabel with html in method
我正在尝试在 Java 中制作固定宽度的标签,我找到了一个解决方案 here。
但是每当我将任何内容放入标签中时,我都会失败——而标签是在方法中创建的。
我的代码在这里:
public class testingGui
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
public static void main(String[] args){
testingGui gui = new testingGui();
gui.init();
}
private void init(){
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setSize(320, 480);
myframe.setVisible(true);
pane_ctn.setLayout(new BoxLayout(pane_ctn, BoxLayout.PAGE_AXIS));
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
pane_ctn.add(lable);
}
}
行 JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
永远不会 运行。 (并使 pane_ctn 变为空白,即使添加了其他 UI 元素)
但是我发现在将标签创建为字段时它可以工作,如下所示:
public class testingGui {
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
// I just cut the whole line and paste here, nothing else has changed.
/* ... */
}
所以这是我的问题:
在方法调用中使用 html 创建标签的正确方法是什么?我需要即时创建它。谢谢。
编辑:
谢谢ybanen给我一个很好的答案,还有其他帮助者。
现在我可以创建看起来不错的标签了。
出现这种情况是因为您在显示后尝试修改 GUI。在您的情况下,最好是创建整个 GUI,然后显示框架:
public class TestingGui {
public static void main(final String[] args) {
final JLabel label = new JLabel("<html>Java is a general-purpose computer programming language</html>");
final JFrame frame = new JFrame("Test");
final Container contentPane = frame.getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
frame.getContentPane().add(label);
frame.setSize(320, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
但是,如果你真的需要在GUI显示后添加标签,你必须遵循几个规则:
- GUI 的任何修改都必须在事件调度线程 (EDT) 中完成。
- 容器显示后,即已布局。所以如果你想在里面添加一个新的组件,你必须强制布局它的内容(使用
revalidate()
然后 repaint()
)。
I need it created on the fly.
为什么?或者更确切地说,为什么不在启动时创建和添加标签,然后在需要时设置文本呢?
My example is a To-Do list, I have a array to store the data, the label is create inside a for loop.
使用 JList
!
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class EditableList {
private JComponent ui = null;
String[] items = {
"Do 100 push ups.",
"Buy a book.",
"Find a cat.",
"Java is a general purpose computer language that is concurrent, "
+ "class based, object oriented and specifically designed to have "
+ "as few implementation dependencies as possible.",
"Conquer the world."
};
EditableList() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
JList<String> list = new JList<String>(items);
list.setCellRenderer(new ToDoListRenderer());
list.getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
ui.add(new JScrollPane(list));
JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER));
controls.add(new JButton("Edit Selected"));
controls.add(new JButton("Delete Selected"));
ui.add(controls, BorderLayout.PAGE_END);
}
class ToDoListRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(
JList<? extends Object> list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
JLabel l = (JLabel)c;
l.setText("<HTML><body style='width: 250px;'>" + value.toString());
return l;
}
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
EditableList o = new EditableList();
JFrame f = new JFrame("To Do List");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
我正在尝试在 Java 中制作固定宽度的标签,我找到了一个解决方案 here。 但是每当我将任何内容放入标签中时,我都会失败——而标签是在方法中创建的。
我的代码在这里:
public class testingGui
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
public static void main(String[] args){
testingGui gui = new testingGui();
gui.init();
}
private void init(){
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setSize(320, 480);
myframe.setVisible(true);
pane_ctn.setLayout(new BoxLayout(pane_ctn, BoxLayout.PAGE_AXIS));
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
pane_ctn.add(lable);
}
}
行 JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
永远不会 运行。 (并使 pane_ctn 变为空白,即使添加了其他 UI 元素)
但是我发现在将标签创建为字段时它可以工作,如下所示:
public class testingGui {
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
// I just cut the whole line and paste here, nothing else has changed.
/* ... */
}
所以这是我的问题: 在方法调用中使用 html 创建标签的正确方法是什么?我需要即时创建它。谢谢。
编辑:
谢谢ybanen给我一个很好的答案,还有其他帮助者。
现在我可以创建看起来不错的标签了。
出现这种情况是因为您在显示后尝试修改 GUI。在您的情况下,最好是创建整个 GUI,然后显示框架:
public class TestingGui {
public static void main(final String[] args) {
final JLabel label = new JLabel("<html>Java is a general-purpose computer programming language</html>");
final JFrame frame = new JFrame("Test");
final Container contentPane = frame.getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
frame.getContentPane().add(label);
frame.setSize(320, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
但是,如果你真的需要在GUI显示后添加标签,你必须遵循几个规则:
- GUI 的任何修改都必须在事件调度线程 (EDT) 中完成。
- 容器显示后,即已布局。所以如果你想在里面添加一个新的组件,你必须强制布局它的内容(使用
revalidate()
然后repaint()
)。
I need it created on the fly.
为什么?或者更确切地说,为什么不在启动时创建和添加标签,然后在需要时设置文本呢?
My example is a To-Do list, I have a array to store the data, the label is create inside a for loop.
使用 JList
!
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class EditableList {
private JComponent ui = null;
String[] items = {
"Do 100 push ups.",
"Buy a book.",
"Find a cat.",
"Java is a general purpose computer language that is concurrent, "
+ "class based, object oriented and specifically designed to have "
+ "as few implementation dependencies as possible.",
"Conquer the world."
};
EditableList() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
JList<String> list = new JList<String>(items);
list.setCellRenderer(new ToDoListRenderer());
list.getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
ui.add(new JScrollPane(list));
JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER));
controls.add(new JButton("Edit Selected"));
controls.add(new JButton("Delete Selected"));
ui.add(controls, BorderLayout.PAGE_END);
}
class ToDoListRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(
JList<? extends Object> list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
JLabel l = (JLabel)c;
l.setText("<HTML><body style='width: 250px;'>" + value.toString());
return l;
}
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
EditableList o = new EditableList();
JFrame f = new JFrame("To Do List");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}