Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="software.aws.toolkits.jetbrains.ui.KeyValueEditor">
<grid id="27dc6" binding="component" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="404" height="85"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="f6744" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="8b151"/>
<text value="Key:"/>
</properties>
</component>
<component id="43628" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="252d7"/>
<text value="Value:"/>
</properties>
</component>
<component id="8b151" class="javax.swing.JTextField" binding="keyField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="250" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="252d7" class="javax.swing.JTextField" binding="valueField" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<columns value="0"/>
</properties>
</component>
<vspacer id="a6f41">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package software.aws.toolkits.jetbrains.ui;

import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Pair;
import java.awt.Component;
import java.util.function.BiFunction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class KeyValueEditor extends DialogWrapper {
private final BiFunction<Pair<String, JComponent>, Pair<String, JComponent>, ValidationInfo> validator;
private JTextField keyField;
private JTextField valueField;
private JPanel component;

public KeyValueEditor(Component parent,
KeyValue initialValue,
BiFunction<Pair<String, JComponent>, Pair<String, JComponent>, ValidationInfo> validator) {
super(parent, false);
this.validator = validator;

if (initialValue == null) {
setTitle("Create New Key-Value");
} else {
setTitle("Edit Key-Value");
keyField.setText(initialValue.getKey());
valueField.setText(initialValue.getValue());
}
init();
}

@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return keyField;
}

@Nullable
@Override
protected JComponent createCenterPanel() {
return component;
}

@Nullable
@Override
protected ValidationInfo doValidate() {
if(validator != null) {
return validator.apply(Pair.create(getKey(), keyField), Pair.create(getValue(), valueField));
} else {
return null;
}
}

@NotNull
@Override
protected Action[] createActions() {
return new Action[] {getOKAction(), getCancelAction()};
}

public String getKey() {
return keyField.getText().trim();
}

public String getValue() {
return valueField.getText().trim();
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="software.aws.toolkits.jetbrains.ui.KeyValueTableEditor">
<grid id="27dc6" binding="content" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c69d5" class="com.intellij.ui.components.JBLabel" binding="remainingItems">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
<visible value="false"/>
</properties>
</component>
<grid id="6ba3f" binding="keyValueTableHolder" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="b679a" class="software.aws.toolkits.jetbrains.ui.KeyValueTable" binding="table">
<constraints border-constraint="Center"/>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package software.aws.toolkits.jetbrains.ui;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.UIUtil;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class KeyValueTableEditor {
private final Supplier<List<KeyValue>> refreshLambda;

private KeyValueTable table;
private JBLabel remainingItems;
private JPanel keyValueTableHolder;
@SuppressWarnings("unused") // Needed in order to embed this into another form
private JPanel content;

private List<KeyValue> initialValues;
private BiFunction<Pair<String, JComponent>, Pair<String, JComponent>, ValidationInfo> entryValidator;

public KeyValueTableEditor(Supplier<List<KeyValue>> refreshLambda, Integer itemLimit,
BiFunction<Pair<String, JComponent>, Pair<String, JComponent>, ValidationInfo> entryValidator,
Runnable changeListener) {
this.refreshLambda = refreshLambda;
this.entryValidator = entryValidator;

ToolbarDecorator toolbar = ToolbarDecorator.createDecorator(table)
.disableUpDownActions()
.setAddAction(e -> this.createOrEdit(null))
.setAddActionUpdater(e -> !table.isBusy())
.setRemoveActionUpdater(e -> !table.isBusy())
.setEditAction(e -> this.createOrEdit(table.getSelectedObject()))
.setEditActionUpdater(e -> !table.isBusy())
.addExtraAction(new AnActionButton("Refresh", AllIcons.Actions.Refresh) {
@Override
public void actionPerformed(AnActionEvent e) {
verifyAndRefresh();
}

@Override
public boolean isEnabled() {
return !table.isBusy();
}
});

table.getModel().addTableModelListener(e -> {
if (itemLimit != null) {
int remaining = itemLimit - (table.getItems().size());
remainingItems.setText("Remaining " + remaining + " of " + itemLimit);
remainingItems.setVisible(true);
} else {
remainingItems.setVisible(false);
}
});

table.getModel().addTableModelListener(e -> changeListener.run());

keyValueTableHolder.add(toolbar.createPanel(), BorderLayout.CENTER);

remainingItems.setForeground(UIUtil.getLabelDisabledForeground());
}

private void verifyAndRefresh() {
if (table.getModel().equals(initialValues)) {
if(!MessageUtils.verifyLossOfChanges(table)) {
return;
}
}

refresh();
}

public void refresh() {
table.setBusy(true);
ApplicationManager.getApplication().executeOnPooledThread(() -> {
if (refreshLambda != null) {
List<KeyValue> updatedValues = refreshLambda.get();
initialValues = updatedValues;
table.getModel().setItems(new ArrayList<>(updatedValues));
}
table.setBusy(false);
});
}

private void createOrEdit(KeyValue selectedObject) {
KeyValueEditor entryEditor = new KeyValueEditor(table, selectedObject, entryValidator);
if (entryEditor.showAndGet()) {
if (selectedObject != null) {
selectedObject.setKey(entryEditor.getKey());
selectedObject.setValue(entryEditor.getValue());
} else {
table.getModel().addRow(new KeyValue(entryEditor.getKey(), entryEditor.getValue()));
}
}
}

public boolean isModified() {
return !table.getItems().equals(initialValues);
}

public void reset() {
table.getModel().setItems(new ArrayList<>(initialValues));
}

public List<KeyValue> getItems() {
return table.getItems();
}

public void setBusy(boolean busy) {
table.setBusy(busy);
}

public boolean isBusy() {
return table.isBusy();
}
}
Loading