Added new choose dialog (creature types and etc):

* added incremental search;
 * added keyboard hotkeys (up/down for select, enter for choose);
 * added choose by mouse double click;
 * added source card name;
 * fixed cancel button on required choice (#4230);
 * fixed text sizes form messages (now it's auto size);
This commit is contained in:
Oleg Agafonov 2017-12-25 08:12:02 +04:00
parent 1efb51a22c
commit 749ca59ad6
7 changed files with 597 additions and 247 deletions

View file

@ -1,13 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo"> <Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="resizable" type="boolean" value="true"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[280, 200]"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<SyntheticProperties> <SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/> <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties> </SyntheticProperties>
@ -26,19 +19,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="335" max="32767" attributes="0"/> <Component id="scrollList" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0"> <Component id="panelCommands" alignment="0" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <Component id="panelHeader" alignment="0" max="32767" attributes="0"/>
<Component id="btnAutoSelect" min="-2" max="-2" attributes="0"/> <Component id="panelSearch" alignment="1" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnOk" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="lblMessage" alignment="0" pref="335" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -47,74 +34,173 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lblMessage" min="-2" pref="37" max="-2" attributes="0"/> <Component id="panelHeader" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="158" max="32767" attributes="0"/> <Component id="panelSearch" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Component id="scrollList" pref="246" max="32767" attributes="0"/>
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="btnOk" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="panelCommands" min="-2" max="-2" attributes="0"/>
<Component id="btnAutoSelect" alignment="3" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JButton" name="btnAutoSelect"> <Container class="javax.swing.JPanel" name="panelHeader">
<Properties>
<Property name="text" type="java.lang.String" value="Auto select"/>
<Property name="toolTipText" type="java.lang.String" value="If you select an effect with &quot;Auto select&quot;, this effect will be selected the next time automatically first."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAutoSelectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnCancel">
<Properties>
<Property name="text" type="java.lang.String" value="Cancel"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnOk">
<Properties>
<Property name="text" type="java.lang.String" value="OK"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnOkActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="labelMessage" alignment="1" pref="210" max="32767" attributes="0"/>
<Component id="labelSubMessage" alignment="1" pref="210" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="labelMessage" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="labelSubMessage" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JList" name="lstChoices"> <Component class="javax.swing.JLabel" name="labelMessage">
<Properties> <Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor"> <Property name="horizontalAlignment" type="int" value="0"/>
<StringArray count="5"> <Property name="text" type="java.lang.String" value="&lt;html&gt;&lt;div style=&apos;text-align: center;&apos;&gt;example long message example long message example long message example long message example long message&lt;/div&gt;&lt;/html&gt;"/>
<StringItem index="0" value="Item 1"/> </Properties>
<StringItem index="1" value="Item 2"/> </Component>
<StringItem index="2" value="Item 3"/> <Component class="javax.swing.JLabel" name="labelSubMessage">
<StringItem index="3" value="Item 4"/> <Properties>
<StringItem index="4" value="Item 5"/> <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
</StringArray> <FontInfo relative="true">
<Font bold="true" component="labelSubMessage" italic="true" property="font" relativeSize="true" size="0"/>
</FontInfo>
</Property> </Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="&lt;html&gt;&lt;div style=&apos;text-align: center;&apos;&gt;example long message example long&lt;/div&gt;&lt;/html&gt;"/>
</Properties> </Properties>
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JLabel" name="lblMessage"> <Container class="javax.swing.JPanel" name="panelSearch">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/> <Layout>
<Property name="text" type="java.lang.String" value="message"/> <DimensionLayout dim="0">
</Properties> <Group type="103" groupAlignment="0" attributes="0">
</Component> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="labelSearch" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="editSearch" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="labelSearch" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editSearch" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelSearch">
<Properties>
<Property name="text" type="java.lang.String" value="Search:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="editSearch">
<Properties>
<Property name="text" type="java.lang.String" value="sample search text"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="scrollList">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="listChoices">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="3">
<StringItem index="0" value="item1"/>
<StringItem index="1" value="item2"/>
<StringItem index="2" value="item3"/>
</StringArray>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value=""/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelCommands">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Component id="btOK" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btCancel" linkSize="3" min="-2" pref="70" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btOK" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="btOK">
<Properties>
<Property name="text" type="java.lang.String" value="Choose"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btOKActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_AddingCodePost" type="java.lang.String" value="getRootPane().setDefaultButton(btOK);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="btCancel">
<Properties>
<Property name="text" type="java.lang.String" value="Cancel"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btCancelActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Form> </Form>

View file

@ -1,43 +1,23 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * To change this license header, choose License Headers in Project Properties.
* * To change this template file, choose Tools | Templates
* Redistribution and use in source and binary forms, with or without modification, are * and open the template in the editor.
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
/*
* PickNumberDialog.java
*
* Created on Feb 25, 2010, 12:03:39 PM
*/ */
package mage.client.dialog; package mage.client.dialog;
import java.awt.Point; import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import mage.choices.Choice; import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.util.SettingsManager; import mage.client.util.SettingsManager;
@ -46,37 +26,103 @@ import mage.client.util.gui.MageDialogState;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author JayDi85
*/ */
public class PickChoiceDialog extends MageDialog { public class PickChoiceDialog extends MageDialog {
/** Creates new form PickNumberDialog */
public PickChoiceDialog() {
initComponents();
this.setModal(true);
}
Choice choice; Choice choice;
boolean autoSelect; ArrayList<KeyValueItem> allItems = new ArrayList<>();
DefaultListModel<KeyValueItem> dataModel = new DefaultListModel();
final private static String HTML_TEMPLATE = "<html><div style='text-align: center;'>%s</div></html>";
public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState) { public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState) {
this.lblMessage.setText("<html>" + choice.getMessage());
this.choice = choice; this.choice = choice;
this.autoSelect = false;
btnAutoSelect.setVisible(choice.isKeyChoice());
if (choice.isKeyChoice()){ setLabelText(this.labelMessage, choice.getMessage());
setLabelText(this.labelSubMessage, choice.getSubMessage());
ComboItem[] comboItems = new ComboItem[choice.getKeyChoices().size()];
int count = 0; btCancel.setEnabled(!choice.isRequired());
for (Map.Entry<String, String> entry : choice.getKeyChoices().entrySet()) {
comboItems[count] = new ComboItem(entry.getKey(), entry.getValue()); // 2 modes: string or key-values
count++; // sore data in allItems for inremental filtering
// http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/
this.allItems.clear();
if (choice.isKeyChoice()){
for (Map.Entry<String, String> entry: choice.getKeyChoices().entrySet()) {
this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue()));
} }
this.lstChoices.setListData(comboItems);
} else { } else {
this.lstChoices.setListData(choice.getChoices().toArray()); for (String value: choice.getChoices()){
this.allItems.add(new KeyValueItem(value, value));
}
} }
// search
if(choice.isSearchEnabled())
{
panelSearch.setVisible(true);
this.editSearch.setText(choice.getSearchText());
}else{
panelSearch.setVisible(false);
this.editSearch.setText("");
}
// listeners for inremental filtering
editSearch.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
choice.setSearchText(editSearch.getText());
loadData();
}
@Override
public void removeUpdate(DocumentEvent e) {
choice.setSearchText(editSearch.getText());
loadData();
}
@Override
public void changedUpdate(DocumentEvent e) {
choice.setSearchText(editSearch.getText());
loadData();
}
});
// listeners for select up and down without edit focus lost
editSearch.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
//System.out.println("types");
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
doPrevSelect();
}else if(e.getKeyCode() == KeyEvent.VK_DOWN){
doNextSelect();
}
}
@Override
public void keyReleased(KeyEvent e) {
//System.out.println("released");
}
});
// listeners double click choose
listChoices.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 2){
doChoose();
}
}
});
// window settings
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
if (mageDialogState != null) { if (mageDialogState != null) {
mageDialogState.setStateToDialog(this); mageDialogState.setStateToDialog(this);
@ -87,154 +133,306 @@ public class PickChoiceDialog extends MageDialog {
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
} }
// final load
loadData();
this.setVisible(true); this.setVisible(true);
} }
public boolean isAutoSelect() { private void loadData(){
return autoSelect; // load data to datamodel after filter or on startup
String filter = choice.getSearchText();
if (filter == null){ filter = ""; }
filter = filter.toLowerCase();
this.dataModel.clear();
for(KeyValueItem item: this.allItems){
if(!choice.isSearchEnabled() || item.Value.toLowerCase().contains(filter)){
this.dataModel.addElement(item);
}
}
}
private void setLabelText(JLabel label, String text){
if ((text != null) && !text.equals("")){
label.setText(String.format(HTML_TEMPLATE, text));
label.setVisible(true);
}else{
label.setText("");
label.setVisible(false);
}
}
private void doNextSelect(){
int newSel = this.listChoices.getSelectedIndex() + 1;
int maxSel = this.listChoices.getModel().getSize() - 1;
if(newSel <= maxSel){
this.listChoices.setSelectedIndex(newSel);
}
}
private void doPrevSelect(){
int newSel = this.listChoices.getSelectedIndex() - 1;
if(newSel >= 0){
this.listChoices.setSelectedIndex(newSel);
}
} }
public void setChoice() { private void doChoose(){
if (this.lstChoices.getSelectedValue() == null) { if(setChoice()){
choice.clearChoice(); this.hideDialog();
}
}
private void doCancel(){
this.listChoices.clearSelection();
this.choice.clearChoice();
hideDialog();
}
/**
* Creates new form PickChoiceDialog
*/
public PickChoiceDialog() {
initComponents();
this.listChoices.setModel(dataModel);
this.setModal(true);
// Close the dialog when Esc is pressed
/*
String cancelName = "cancel";
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
ActionMap actionMap = getRootPane().getActionMap();
actionMap.put(cancelName, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
doCancel();
}
});
*/
}
public boolean setChoice() {
KeyValueItem item = (KeyValueItem)this.listChoices.getSelectedValue();
// auto select one item (after incemental filtering)
if((item == null) && (this.listChoices.getModel().getSize() == 1)){
this.listChoices.setSelectedIndex(0);
item = (KeyValueItem)this.listChoices.getSelectedValue();
} }
if (choice.isKeyChoice()) { if(item != null){
ComboItem item = (ComboItem)this.lstChoices.getSelectedValue(); if(choice.isKeyChoice()){
if (item != null) { choice.setChoiceByKey(item.getKey());
choice.setChoiceByKey(item.getValue()); }else{
} else { choice.setChoice(item.getKey());
choice.clearChoice();
} }
} else { return true;
choice.setChoice((String)this.lstChoices.getSelectedValue()); }else{
choice.clearChoice();
return false;
} }
} }
class KeyValueItem
{
private final String Key;
private final String Value;
public KeyValueItem(String value, String label) {
this.Key = value;
this.Value = label;
}
/** This method is called from within the constructor to public String getKey() {
* initialize the form. return this.Key;
* WARNING: Do NOT modify this code. The content of this method is }
* always regenerated by the Form Editor.
public String getValue() {
return this.Value;
}
@Override
public String toString() {
return this.Value;
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
btnAutoSelect = new javax.swing.JButton(); panelHeader = new javax.swing.JPanel();
btnCancel = new javax.swing.JButton(); labelMessage = new javax.swing.JLabel();
btnOk = new javax.swing.JButton(); labelSubMessage = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane(); panelSearch = new javax.swing.JPanel();
lstChoices = new javax.swing.JList(); labelSearch = new javax.swing.JLabel();
lblMessage = new javax.swing.JLabel(); editSearch = new javax.swing.JTextField();
scrollList = new javax.swing.JScrollPane();
listChoices = new javax.swing.JList();
panelCommands = new javax.swing.JPanel();
btOK = new javax.swing.JButton();
btCancel = new javax.swing.JButton();
setResizable(true); labelMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
setMinimumSize(new java.awt.Dimension(280, 200)); labelMessage.setText("<html><div style='text-align: center;'>example long message example long message example long message example long message example long message</div></html>");
setName(""); // NOI18N
btnAutoSelect.setText("Auto select"); labelSubMessage.setFont(labelSubMessage.getFont().deriveFont((labelSubMessage.getFont().getStyle() | java.awt.Font.ITALIC) | java.awt.Font.BOLD));
btnAutoSelect.setToolTipText("If you select an effect with \"Auto select\", this effect will be selected the next time automatically first."); labelSubMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
btnAutoSelect.addActionListener(evt -> btnAutoSelectActionPerformed(evt)); labelSubMessage.setText("<html><div style='text-align: center;'>example long message example long</div></html>");
btnCancel.setText("Cancel"); javax.swing.GroupLayout panelHeaderLayout = new javax.swing.GroupLayout(panelHeader);
btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt)); panelHeader.setLayout(panelHeaderLayout);
panelHeaderLayout.setHorizontalGroup(
panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelHeaderLayout.createSequentialGroup()
.addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
.addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
.addGap(0, 0, 0))
);
panelHeaderLayout.setVerticalGroup(
panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelHeaderLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(labelMessage)
.addGap(0, 0, 0)
.addComponent(labelSubMessage))
);
btnOk.setText("OK"); labelSearch.setText("Search:");
btnOk.addActionListener(evt -> btnOkActionPerformed(evt));
lstChoices.setModel(new javax.swing.AbstractListModel() { editSearch.setText("sample search text");
final String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
javax.swing.GroupLayout panelSearchLayout = new javax.swing.GroupLayout(panelSearch);
panelSearch.setLayout(panelSearchLayout);
panelSearchLayout.setHorizontalGroup(
panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelSearchLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(labelSearch)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(editSearch)
.addGap(0, 0, 0))
);
panelSearchLayout.setVerticalGroup(
panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelSearchLayout.createSequentialGroup()
.addGap(3, 3, 3)
.addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(labelSearch)
.addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(3, 3, 3))
);
listChoices.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "item1", "item2", "item3" };
public int getSize() { return strings.length; } public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; } public Object getElementAt(int i) { return strings[i]; }
}); });
jScrollPane1.setViewportView(lstChoices); scrollList.setViewportView(listChoices);
lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); btOK.setText("Choose");
lblMessage.setText("message"); btOK.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btOKActionPerformed(evt);
}
});
btCancel.setText("Cancel");
btCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btCancelActionPerformed(evt);
}
});
javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands);
panelCommands.setLayout(panelCommandsLayout);
panelCommandsLayout.setHorizontalGroup(
panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelCommandsLayout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btOK)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btCancel, btOK});
panelCommandsLayout.setVerticalGroup(
panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelCommandsLayout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btCancel)
.addComponent(btOK))
.addContainerGap())
);
getRootPane().setDefaultButton(btOK);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE) .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup() .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, Short.MAX_VALUE) .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnAutoSelect) .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnOk)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel))
.addComponent(lblMessage, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(6, 6, 6) .addContainerGap()
.addComponent(lblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE) .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
.addComponent(btnCancel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnOk) .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnAutoSelect)) .addContainerGap())
.addGap(10, 10, 10))
); );
pack(); pack();
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed private void btOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btOKActionPerformed
setChoice(); doChoose();
this.hideDialog(); }//GEN-LAST:event_btOKActionPerformed
}//GEN-LAST:event_btnOkActionPerformed
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed private void btCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btCancelActionPerformed
this.lstChoices.clearSelection(); doCancel();
this.choice.clearChoice(); }//GEN-LAST:event_btCancelActionPerformed
this.hideDialog();
}//GEN-LAST:event_btnCancelActionPerformed
private void btnAutoSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAutoSelectActionPerformed /**
this.autoSelect = true; * Closes the dialog
setChoice(); */
this.hideDialog(); private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
}//GEN-LAST:event_btnAutoSelectActionPerformed doCancel();
}//GEN-LAST:event_closeDialog
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnAutoSelect; private javax.swing.JButton btCancel;
private javax.swing.JButton btnCancel; private javax.swing.JButton btOK;
private javax.swing.JButton btnOk; private javax.swing.JTextField editSearch;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel labelMessage;
private javax.swing.JLabel lblMessage; private javax.swing.JLabel labelSearch;
private javax.swing.JList lstChoices; private javax.swing.JLabel labelSubMessage;
private javax.swing.JList listChoices;
private javax.swing.JPanel panelCommands;
private javax.swing.JPanel panelHeader;
private javax.swing.JPanel panelSearch;
private javax.swing.JScrollPane scrollList;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }
class ComboItem {
private final String value;
private final String label;
public ComboItem(String value, String label) {
this.value = value;
this.label = label;
}
public String getValue() {
return this.value;
}
public String getLabel() {
return this.label;
}
@Override
public String toString() {
return label;
}
}

View file

@ -1220,14 +1220,17 @@ public final class GamePanel extends javax.swing.JPanel {
public void getChoice(Choice choice, UUID objectId) { public void getChoice(Choice choice, UUID objectId) {
hideAll(); hideAll();
// TODO: remember last choices and search incremental for same events?
PickChoiceDialog pickChoice = new PickChoiceDialog(); PickChoiceDialog pickChoice = new PickChoiceDialog();
pickChoice.showDialog(choice, objectId, choiceWindowState); pickChoice.showDialog(choice, objectId, choiceWindowState);
if (choice.isKeyChoice()) { if (choice.isKeyChoice()) {
SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
/* // old code, auto complete was for auto scripting?
if (pickChoice.isAutoSelect()) { if (pickChoice.isAutoSelect()) {
SessionHandler.sendPlayerString(gameId, '#' + choice.getChoiceKey()); SessionHandler.sendPlayerString(gameId, '#' + choice.getChoiceKey());
} else { } else {
SessionHandler.sendPlayerString(gameId, choice.getChoiceKey()); SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
} }*/
} else { } else {
SessionHandler.sendPlayerString(gameId, choice.getChoice()); SessionHandler.sendPlayerString(gameId, choice.getChoice());
} }

View file

@ -33,6 +33,7 @@ import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceCreatureType;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
@ -63,9 +64,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
mageObject = game.getObject(source.getSourceId()); mageObject = game.getObject(source.getSourceId());
} }
if (controller != null && mageObject != null) { if (controller != null && mageObject != null) {
Choice typeChoice = new ChoiceImpl(true); Choice typeChoice = new ChoiceCreatureType(mageObject);
typeChoice.setMessage("Choose creature type");
typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
while (!controller.choose(outcome, typeChoice, game)) { while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) { if (!controller.canRespond()) {
return false; return false;

View file

@ -37,19 +37,34 @@ import java.util.Set;
*/ */
public interface Choice { public interface Choice {
boolean isChosen();
boolean isRequired();
void clearChoice();
String getMessage(); String getMessage();
void setMessage(String message); void setMessage(String message);
void setChoice(String choice);
void setChoiceByKey(String choiceKey); String getSubMessage();
Set<String> getChoices(); void setSubMessage(String subMessage);
Map<String,String> getKeyChoices();
void setChoices(Set<String> choices); void clearChoice();
void setKeyChoices(Map<String, String> choices); boolean isChosen();
String getChoice(); boolean isRequired();
String getChoiceKey();
boolean isKeyChoice();
Choice copy(); Choice copy();
// string choice
void setChoices(Set<String> choices);
Set<String> getChoices();
void setChoice(String choice);
String getChoice();
// key-value choice
boolean isKeyChoice();
void setKeyChoices(Map<String, String> choices);
Map<String,String> getKeyChoices();
void setChoiceByKey(String choiceKey);
String getChoiceKey();
// search
boolean isSearchEnabled();
void setSearchEnabled(boolean isEnabled);
void setSearchText(String searchText);
String getSearchText();
} }

View file

@ -1,5 +1,6 @@
package mage.choices; package mage.choices;
import mage.MageObject;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -7,10 +8,28 @@ import java.util.stream.Collectors;
public class ChoiceCreatureType extends ChoiceImpl { public class ChoiceCreatureType extends ChoiceImpl {
private static String DEFAULT_MESSAGE = "Choose a creature type";
public ChoiceCreatureType() { public ChoiceCreatureType() {
super(true); this(true, DEFAULT_MESSAGE, null);
}
public ChoiceCreatureType(MageObject source) {
this(true, DEFAULT_MESSAGE, source);
}
public ChoiceCreatureType(String chooseMessage, MageObject source) {
this(true, chooseMessage, source);
}
public ChoiceCreatureType(boolean required, String chooseMessage, MageObject source){
super(required);
this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new))); this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
this.message = "Choose a creature type:"; this.setMessage(chooseMessage);
if(source != null) {
this.setSubMessage(source.getIdName());
}
this.setSearchEnabled(true);
} }
public ChoiceCreatureType(final ChoiceCreatureType choice) { public ChoiceCreatureType(final ChoiceCreatureType choice) {

View file

@ -47,6 +47,9 @@ public class ChoiceImpl implements Choice, Serializable {
protected Set<String> choices = new LinkedHashSet<>(); protected Set<String> choices = new LinkedHashSet<>();
protected Map<String, String> keyChoices = new LinkedHashMap<>(); protected Map<String, String> keyChoices = new LinkedHashMap<>();
protected String message; protected String message;
protected String subMessage;
protected boolean searchEnabled;
protected String searchText;
public ChoiceImpl() { public ChoiceImpl() {
this(false); this(false);
@ -61,6 +64,7 @@ public class ChoiceImpl implements Choice, Serializable {
this.chosen = choice.chosen; this.chosen = choice.chosen;
this.required = choice.required; this.required = choice.required;
this.message = choice.message; this.message = choice.message;
this.message = choice.subMessage;
this.choices.addAll(choice.choices); this.choices.addAll(choice.choices);
this.choiceKey = choice.choiceKey; this.choiceKey = choice.choiceKey;
this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference
@ -88,6 +92,12 @@ public class ChoiceImpl implements Choice, Serializable {
this.message = message; this.message = message;
} }
@Override
public String getSubMessage(){ return subMessage; }
@Override
public void setSubMessage(String subMessage){ this.subMessage = subMessage; }
@Override @Override
public Set<String> getChoices() { public Set<String> getChoices() {
return choices; return choices;
@ -150,4 +160,24 @@ public class ChoiceImpl implements Choice, Serializable {
return !keyChoices.isEmpty(); return !keyChoices.isEmpty();
} }
} @Override
public boolean isSearchEnabled(){
return this.searchEnabled;
};
@Override
public void setSearchEnabled(boolean isEnabled){
this.searchEnabled = isEnabled;
};
@Override
public void setSearchText(String searchText){
this.searchText = searchText;
};
@Override
public String getSearchText(){
return this.searchText;
};
}