refactor: extract common ListModel implementation to AtListModel

and use that for moving elements up and down
This commit is contained in:
OMGeeky
2025-06-16 09:46:14 +02:00
parent 719be70744
commit 64ea5377bf
2 changed files with 115 additions and 89 deletions

View File

@@ -911,87 +911,19 @@ public class DialogueEditor extends JSONElementEditor {
} }
public static class RepliesListModel implements ListModel<Dialogue.Reply> { public static class RepliesListModel extends CommonEditor.AtListModel<Dialogue.Reply, Dialogue> {
Dialogue source;
public RepliesListModel(Dialogue dialogue) { public RepliesListModel(Dialogue dialogue) {
this.source = dialogue; super(dialogue);
}
@Override
public int getSize() {
if (source.replies == null) return 0;
return source.replies.size();
} }
@Override @Override
public Dialogue.Reply getElementAt(int index) { protected List<Dialogue.Reply> getInner() {
if (source.replies == null) return null; return source.replies;
return source.replies.get(index);
}
public void addItem(Dialogue.Reply item) {
if (source.replies == null) {
source.replies = new ArrayList<Dialogue.Reply>();
}
source.replies.add(item);
int index = source.replies.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
source.replies.remove(item);
if (source.replies.isEmpty()) {
source.replies = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void moveUp(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
Dialogue.Reply exchanged = source.replies.get(index - 1);
source.replies.set(index, exchanged);
source.replies.set(index - 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index - 1, index));
}
}
public void moveDown(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
Dialogue.Reply exchanged = source.replies.get(index + 1);
source.replies.set(index, exchanged);
source.replies.set(index + 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index + 1));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
public void removeListDataListener(ListDataListener l) { protected void setInner(List<Dialogue.Reply> value) {
listeners.remove(l); source.replies = value;
} }
} }

View File

@@ -9,20 +9,25 @@ import com.gpl.rpg.atcontentstudio.utils.lambda.CallWithThreeArgs;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public final class CommonEditor { public final class CommonEditor {
public static <E> CollapsiblePanel createListPanel(String title, public static <E, S> CollapsiblePanel createListPanel(String title,
ListCellRenderer<? super E> cellRenderer, ListCellRenderer<? super E> cellRenderer,
ListModel<E> listModel, AtListModel<E, S> listModel,
boolean isCollapsed, boolean isCollapsed,
boolean writable, boolean writable,
CallWithSingleArg<E> selectedValueSetter, CallWithSingleArg<E> selectedValueSetter,
CallWithReturn<E> selectedValueGetter, CallWithReturn<E> selectedValueGetter,
CallWithThreeArgs<JPanel, E, FieldUpdateListener> updateRepliesEditorPane, CallWithThreeArgs<JPanel, E, FieldUpdateListener> updateRepliesEditorPane,
FieldUpdateListener listener, FieldUpdateListener listener,
CallWithReturn<E> createNew) { CallWithReturn<E> createNew) {
CollapsiblePanel replies = new CollapsiblePanel(title); CollapsiblePanel replies = new CollapsiblePanel(title);
replies.setLayout(new JideBoxLayout(replies, JideBoxLayout.PAGE_AXIS)); replies.setLayout(new JideBoxLayout(replies, JideBoxLayout.PAGE_AXIS));
JList<E> repliesList = new JList<>(listModel); JList<E> repliesList = new JList<>(listModel);
@@ -38,7 +43,7 @@ public final class CommonEditor {
moveReplyUp.setEnabled(false); moveReplyUp.setEnabled(false);
moveReplyDown.setEnabled(false); moveReplyDown.setEnabled(false);
repliesList.addListSelectionListener(e -> { repliesList.addListSelectionListener(e -> {
E selectedReply = repliesList.getSelectedValue(); E selectedReply = repliesList.getSelectedValue();
selectedValueSetter.call(selectedReply); selectedValueSetter.call(selectedReply);
if (selectedReply != null) { if (selectedReply != null) {
deleteReply.setEnabled(true); deleteReply.setEnabled(true);
@@ -56,14 +61,14 @@ public final class CommonEditor {
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createReply.addActionListener(e -> { createReply.addActionListener(e -> {
E created = createNew.call(); E created = createNew.call();
// listModel.addItem(created);//TODO listModel.addItem(created);
repliesList.setSelectedValue(created, true); repliesList.setSelectedValue(created, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}); });
deleteReply.addActionListener(e -> { deleteReply.addActionListener(e -> {
E selected = selectedValueGetter.call(); E selected = selectedValueGetter.call();
if (selected != null) { if (selected != null) {
// listModel.removeItem(selected);//TODO listModel.removeItem(selected);
selected = null; selected = null;
selectedValueSetter.call(selected); selectedValueSetter.call(selected);
repliesList.clearSelection(); repliesList.clearSelection();
@@ -73,7 +78,7 @@ public final class CommonEditor {
moveReplyUp.addActionListener(e -> { moveReplyUp.addActionListener(e -> {
E selected = selectedValueGetter.call(); E selected = selectedValueGetter.call();
if (selected != null) { if (selected != null) {
// listModel.moveUp(selected);//TODO listModel.moveUp(selected);
repliesList.setSelectedValue(selected, true); repliesList.setSelectedValue(selected, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
} }
@@ -81,7 +86,7 @@ public final class CommonEditor {
moveReplyDown.addActionListener(e -> { moveReplyDown.addActionListener(e -> {
E selected = selectedValueGetter.call(); E selected = selectedValueGetter.call();
if (selected != null) { if (selected != null) {
// listModel.moveDown(selected);//TODO listModel.moveDown(selected);
repliesList.setSelectedValue(selected, true); repliesList.setSelectedValue(selected, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
} }
@@ -119,4 +124,93 @@ public final class CommonEditor {
//:: Split //:: Split
return in.substring(0, spaceIndex).trim() + newline + wordWrap(in.substring(spaceIndex), length); return in.substring(0, spaceIndex).trim() + newline + wordWrap(in.substring(spaceIndex), length);
} }
public abstract static class AtListModel<E, S> implements ListModel<E> {
protected S source;
protected abstract List<E> getInner();
protected abstract void setInner(List<E> value);
public AtListModel(S source) {
this.source = source;
}
@Override
public int getSize() {
if (getInner() == null) return 0;
return getInner().size();
}
@Override
public E getElementAt(int index) {
if (getInner() == null) return null;
return getInner().get(index);
}
public void addItem(E item) {
if (getInner() == null) {
setInner(new ArrayList<>());
}
getInner().add(item);
int index = getInner().indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(E item) {
int index = getInner().indexOf(item);
getInner().remove(item);
if (getInner().isEmpty()) {
setInner(null);
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(E item) {
int index = getInner().indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void moveUp(E item) {
int index = getInner().indexOf(item);
E exchanged = getInner().get(index - 1);
getInner().set(index, exchanged);
getInner().set(index - 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index - 1, index));
}
}
public void moveDown(E item) {
int index = getInner().indexOf(item);
E exchanged = getInner().get(index + 1);
getInner().set(index, exchanged);
getInner().set(index + 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index + 1));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
} }