你很亲密。
在列表中添加和删除元素时,您确实需要触发一个事件,但这是模型的责任,而不是微调器。所以你必须实现你自己的模型。
另一个问题是当列表被清空时,微调器没有任何东西可以显示,这可能就是你得到异常的原因。
所以你必须决定当微调器被清空时该怎么做。
例如,假设您希望微调器在它为空时被禁用,并在它不为空时重新启用。
正如我之前告诉你的,你必须实现你的SpinnerListModel
以便手动触发添加和删除的事件。但是现在您还希望根据模型禁用和启用微调器。因此,您可以实现模型以获取微调器的参考...
遵循示例代码:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;
public class ImageDealer2 {
public static class RemoveSpinnerListModel extends SpinnerListModel {
private static final String VALUE_OF_EMPTY_LIST = ""; //This value indicates the spinner is empty.
protected JSpinner spin; //The spinner which this model referes to.
private boolean empty; //indicates if the list spinner is empty.
//The spinner is empty if it contains only the VALUE_OF_EMPTY_LIST value.
public RemoveSpinnerListModel() {
super(new ArrayList(Arrays.asList(VALUE_OF_EMPTY_LIST))); //We initialize to an "empty" read-write list.
empty = true; //The spinner does not contain any valid value.
}
public void setSpinner(final JSpinner spin) {
this.spin = Objects.requireNonNull(spin); //Just a null check plus assignment.
//We ensure the list has at least one element in it (the VALUE_OF_EMPTY_LIST):
if (getList().isEmpty())
((List)getList()).add(VALUE_OF_EMPTY_LIST);
//The spinner is empty if and only if the list contains only the VALUE_OF_EMPTY_LIST.
empty = getList().size() == 1 && getList().get(0).equals(VALUE_OF_EMPTY_LIST);
//We enable/disable the spinner accordingly:
spin.setEnabled(!empty);
if (empty) //If the spinner is empty of valid values:
spin.setValue(VALUE_OF_EMPTY_LIST); //then we add the VALUE_OF_EMPTY_LIST.
}
public void add(final Object value) {
if (empty) //If the spinner contains only the VALUE_OF_EMPTY_LIST, then:
getList().clear(); //Remove the VALUE_OF_EMPTY_LIST string.
((List)getList()).add(value); //Add the requested value.
if (spin != null) {
spin.setEnabled(true); //Enable the spinner for sure, because now it has at least one valid value.
spin.setValue(value);
}
empty = false; //The spinner is surely not empty.
fireStateChanged(); //Important step: updates the spinner via firing an event in the model.
}
public void remove(final Object value) {
if (!getList().isEmpty()) { //If there is something to remove.
getList().remove(value); //Remove the requested value.
if (getList().isEmpty()) //If now the list is empty, then we mark the spinner as empty:
markTheSpinnerAsEmpty();
else //Else the list still contains valid elements, so we mark the spinner as not-empty:
empty = false;
}
else //Else, the list is empty, so nothing to remove and the spinner must be marked as empty:
markTheSpinnerAsEmpty();
if (spin != null)
spin.setEnabled(!empty);
fireStateChanged(); //Important step: updates the spinner via firing an event in the model.
}
public void clear() {
getList().clear(); //Remove everything for sure.
markTheSpinnerAsEmpty();
}
private void markTheSpinnerAsEmpty() {
((List)getList()).add(VALUE_OF_EMPTY_LIST);
if (spin != null) {
spin.setValue(VALUE_OF_EMPTY_LIST); //Let's show the user that nothing is here.
spin.setEnabled(false);
}
empty = true;
}
}
protected JFrame selectCoverFrame;
protected JSpinner spinnerCovers;
protected JButton deleteCoverButton;
protected RemoveSpinnerListModel spinnerCoversM;
public ImageDealer2() {
selectFrameInit();
}
private void selectFrameInit() {
selectCoverFrame = new JFrame("Select");
selectCoverFrame.setSize(new Dimension(500, 100));
selectCoverFrame.getContentPane().setLayout(new BoxLayout(selectCoverFrame.getContentPane(), BoxLayout.Y_AXIS));
spinnerCoversM = new RemoveSpinnerListModel();
spinnerCoversM.add("a");
spinnerCoversM.add("b");
spinnerCoversM.add("c");
spinnerCoversM.add("d");
spinnerCovers = new JSpinner(spinnerCoversM);
spinnerCoversM.setSpinner(spinnerCovers); //DO NOT forget this step!
deleteCoverButton = new JButton("Delete current element");
DeleteCurrentCoverHandler deleteCurrentCoverHandler = new DeleteCurrentCoverHandler();
deleteCoverButton.addActionListener(deleteCurrentCoverHandler);
final JButton addButton = new JButton("Add an element");
AddANewCoverHandler addANewCoverHandler = new AddANewCoverHandler();
addButton.addActionListener(addANewCoverHandler);
final JPanel buttonPanel = new JPanel(); //FlowLayout.
buttonPanel.add(deleteCoverButton);
buttonPanel.add(addButton);
selectCoverFrame.getContentPane().add(spinnerCovers);
selectCoverFrame.getContentPane().add(buttonPanel);
selectCoverFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //With this call, when you close the frame, then the application gets terminated.
selectCoverFrame.setLocationRelativeTo(null); //With this call, the frame gets to the center of the screen.
selectCoverFrame.setVisible(true);
}
private class DeleteCurrentCoverHandler implements ActionListener {
@Override
public void actionPerformed(final ActionEvent e) {
spinnerCoversM.remove(spinnerCovers.getValue());
}
}
private class AddANewCoverHandler implements ActionListener {
@Override
public void actionPerformed(final ActionEvent e) {
spinnerCoversM.add(JOptionPane.showInputDialog("Enter the new element string:"));
}
}
public static void main(final String[] args) {
new ImageDealer2();
}
}
如果要从微调器中添加或删除任何对象,则必须通过此模型进行。
对于任何其他“只读”操作(例如isEmpty()
和size()
),您可以调用getList()
模型的 。
也许这是一个比预期更大的解决方案,但它是可重用的。