![](/img/trans.png)
[英]Swing JTextField text changed listener DocumentListener infinity loop
[英]JTextField in a loop of slider listener
我是Java編程的初學者,遇到問題。 我的目標是關聯滑條,該滑條可為我提供多個圖形的頂點,並同時創建圖片上坐標的JFieldText字段:
我的嘗試導致了我在創建這些字段時遇到的問題,盡管在GridLayout中取2卻有很多列,而當我減小頂點的值時,字段卻沒有。 這是我的代碼示例:
int vertices = 3;
slider.addChangeListener(new SpinerListener());
class SpinerListener implements ChangeListener {
public void stateChanged(ChangeEvent arg0) {
vertices = slider.getValue();
right.setLayout(new GridLayout(vertices, 2));//right is my panel
for (int i = 0; i < vertices*2; i++) {
fields[i] = new JTextField("Field " + i);
right.add(fields[i]);
}
right.removeAll();
}
}
使用某種List
-提供一個可動態調整大小的對象容器的概念,而不是使用數組。 這樣,您就可以根據JSlider
的新值確定是否需要從List
添加或刪除項目。
private List<JTextField[]> fields = new ArrayList<>(3);
//....
class SpinerListener implements ChangeListener {
public void stateChanged(ChangeEvent arg0) {
vertices = slider.getValue();
if (vertices < fields.size()) {
List<JTextField[]> oldFields = fields.subList(vertices + 1, fields.size());
for (JTextField[] pairs : oldFields) {
for (JTextField field : pairs) {
right.remove(field);
}
}
fields.removeAll(oldFields);
right.revalidate();
right.repaint();
} else if (vertices > fields.size()) {
int count = (vertices - fields.size());
System.out.println("Add " + count + " new fields");
for (int index = 0; index < count; index++) {
JTextField[] pairs = new JTextField[2];
pairs[0] = new JTextField(4);
pairs[1] = new JTextField(4);
for (JTextField field : pairs) {
right.add(field);
}
fields.add(pairs);
}
right.revalidate();
right.repaint();
}
}
}
因此,這很基本,它只是將字段對的數量與所需數量進行比較,並相應地增大或縮小List
。
至於GridLayout
,您實際上只需要設置一次...
right = new JPanel(new GridLayout(0, 2));
參數:
rows-行,值為零表示任意數量的行。
cols-列,值為零表示任意數量的列。
但是,就我個人而言,我很想使用GridBagLayout
,但這就是我
而且因為我必須測試邏輯...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JSlider slider;
private int vertices = 3;
private List<JTextField[]> fields = new ArrayList<>(3);
private JPanel right;
public TestPane() {
setLayout(new BorderLayout());
right = new JPanel(new GridLayout(0, 2));
add(new JScrollPane(right));
slider = new JSlider();
slider.addChangeListener(new SpinerListener());
slider.setValue(vertices);
add(slider, BorderLayout.NORTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
class SpinerListener implements ChangeListener {
public void stateChanged(ChangeEvent arg0) {
vertices = slider.getValue();
if (vertices < fields.size()) {
List<JTextField[]> oldFields = fields.subList(vertices + 1, fields.size());
for (JTextField[] pairs : oldFields) {
for (JTextField field : pairs) {
right.remove(field);
}
}
fields.removeAll(oldFields);
right.revalidate();
right.repaint();
} else if (vertices > fields.size()) {
int count = (vertices - fields.size());
System.out.println("Add " + count + " new fields");
for (int index = 0; index < count; index++) {
JTextField[] pairs = new JTextField[2];
pairs[0] = new JTextField(4);
pairs[1] = new JTextField(4);
for (JTextField field : pairs) {
right.add(field);
}
fields.add(pairs);
}
right.revalidate();
right.repaint();
}
}
}
}
}
使用JTable
,它可能更簡單,更易於管理-有關更多詳細信息,請參見如何使用表
如果你必須使用JTextField的情況,然后才重新添加新JTextFields將首先刪除所有JTextField的聽者。 可以將GridLayout(0, 2)
用於所有對象,因為這意味着2列和可變行。
可能更好:使用JTable並只需更改行數即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.