我想根据您在文本字段中首先编写的数字(不允许使用字符串)打印多个标签。我希望它是动态的。我希望每次在文本字段中输入内容时都要更改它。
到目前为止,如果文本不符合要求,它可以读取数字或字符串并抛出异常。
我尝试多种方法在屏幕上打印多个Jlabel,但到目前为止它还没有工作。
以下是代码:你能帮助我吗?
主窗口类
public class MainWindow extends JFrame {
private MainPanel mp = new MainPanel();
public MainWindow()
{
this.setVisible(true);
this.setTitle("Calculateur sur 100");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(200, 400);
this.setLocationRelativeTo(null);
this.setContentPane(mp);
}}
mainPanel类
public class MainPanel extends JPanel implements ActionListener, MouseListener, KeyListener {
private JTextField tI = new JTextField("Pourcentage");
private JOptionPane jop3 = new JOptionPane();
public MainPanel()
{
this.add(tI);
tI.addKeyListener(this);
tI.addMouseListener(this);
}
//Mathematic calculation
private double onHundred(int tot, int now)
{
return (tot / 100) * now;
}
public void keyReleased(KeyEvent e)
{
boolean ok = true;
try
{
int numbs = Integer.parseInt(tI.getText());
}
catch(Exception s)
{
tI.setText("");
jop3.showMessageDialog(null, "Veuillez entrer seulement des chiffres", "Erreur", JOptionPane.ERROR_MESSAGE);
ok = false;
}
if(ok)
{
System.out.print("Supposed to print");
JLabel[] label = new JLabel[Integer.parseInt(tI.getText())];
for(int i = Integer.parseInt(tI.getText()); i <= 0; i--)
{
label[i] = new JLabel(i + " = " + Math.ceil(onHundred(Integer.parseInt(tI.getText()), i)));
label[i].setVisible(true);
this.add(label[i]);
}
}
}
答案 0 :(得分:1)
首先 - 您在同一个Integer.parseInt(tI.getText())
函数中多次keyReleased
次。完成第一次检查后将其分配给int numbs
,然后再使用numbs
,而不是引用回tI.getText()
。从理论上讲,在处理数组时,用户输入可能会发生变化,从而导致运行时异常或意外结果。提示 - 直接在numbs
下声明ok
。
其次 - 以编程方式添加控件后,您需要invalidate
您要添加控件的控件,即MainPanel
。 invalidate
指令告诉控件它没有正确绘制并需要重新绘制(在循环完成时执行此操作)。查看JPanel的文档invalidate
和paint
。
答案 1 :(得分:1)
你MainWindow
课应该是这样的:
public class MainWindow extends JFrame {
private MainPanel mp = new MainPanel();
public static void main(String[] args) {
new MainWindow();
}
public MainWindow() {
setContentPane(mp);
setTitle("Calculateur sur 100");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
请注意订单:setContentPane
然后pack
然后setVisible
。 pack
替换setSize
,因为它根据窗口组件确定窗口的首选大小。
我修改了你的MainPanel
课程:
public class MainPanel extends JPanel {
private JTextField tI = new JTextField("Pourcentage");
JPanel labelPanel = new JPanel();
public MainPanel() {
setLayout(new BorderLayout());
tI.getDocument().addDocumentListener(new MyDocumentListener());
add(tI, BorderLayout.PAGE_START);
add(labelPanel);
}
private int check() {
int numL;
try {
numL = Integer.parseInt(tI.getText());
} catch (NumberFormatException exc) {
return 0;
}
return numL > 100? 100 : numL;
}
private void update(int numL) {
labelPanel.removeAll();
for (int i = 0; i < numL; i++)
labelPanel.add(new JLabel(String.valueOf(i+1)));
JFrame mainWindow = ((JFrame) SwingUtilities.getWindowAncestor(this));
mainWindow.pack();
mainWindow.repaint();
}
class MyDocumentListener implements DocumentListener {
@Override
public void insertUpdate(DocumentEvent e) {
update(check());
}
@Override
public void removeUpdate(DocumentEvent e) {
update(check());
}
@Override
public void changedUpdate(DocumentEvent e) {
}
}
}
<强>解释强>
DocumentListener
代替KeyListener
来监听其内容的更改。这是正确的方法,除非真的有必要,否则我不会进入这里。check
方法都会验证输入是否为数字。如果不是,则返回0.如果超过100,则返回100.您可以根据需要更改此行为。check
的值传递给update
,它会清除所有以前的标签并重新构建它们。 (你可以在这里进行一些优化,如果你想通过将标签保留在内存中但不显示它们。如果上限为100,如我的例子所示,这将是不明显的。)。然后主框架重新计算所有标签所需的空间,然后重新绘制。JPanel
的默认布局为FlowLayout
。您可以根据需要进行更改。