/** * Copyright (c) 2005-2017, KoLmafia development team * http://kolmafia.sourceforge.net/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are 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. * [3] Neither the name "KoLmafia" nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 THE * COPYRIGHT OWNER 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. */ package net.sourceforge.kolmafia.swingui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.font.TextAttribute; import java.io.Serializable; import java.util.EventObject; import java.util.HashMap; import java.util.Map; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SpringLayout; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.event.CellEditorListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.text.BadLocationException; import org.jdesktop.swingx.JXGlassBox; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.decorator.AbstractHighlighter; import org.jdesktop.swingx.decorator.ColorHighlighter; import org.jdesktop.swingx.decorator.ComponentAdapter; import org.jdesktop.swingx.decorator.CompoundHighlighter; import org.jdesktop.swingx.decorator.HighlightPredicate; import org.jdesktop.swingx.decorator.Highlighter; import org.jdesktop.swingx.decorator.HighlighterFactory; import org.jdesktop.swingx.renderer.DefaultTableRenderer; import org.jdesktop.swingx.rollover.RolloverProducer; import net.java.dev.spellcast.utilities.JComponentUtilities; import net.java.dev.spellcast.utilities.LockableListModel; import net.java.dev.spellcast.utilities.SortedListModel; import net.sourceforge.kolmafia.AdventureResult; import net.sourceforge.kolmafia.KoLConstants; import net.sourceforge.kolmafia.KoLmafia; import net.sourceforge.kolmafia.RequestThread; import net.sourceforge.kolmafia.persistence.ItemDatabase; import net.sourceforge.kolmafia.request.AutoMallRequest; import net.sourceforge.kolmafia.request.AutoSellRequest; import net.sourceforge.kolmafia.request.ManageStoreRequest; import net.sourceforge.kolmafia.session.StoreManager; import net.sourceforge.kolmafia.session.StoreManager.SoldItem; import net.sourceforge.kolmafia.swingui.listener.ThreadedListener; import net.sourceforge.kolmafia.swingui.panel.GenericPanel; import net.sourceforge.kolmafia.swingui.panel.ItemListManagePanel; import net.sourceforge.kolmafia.swingui.panel.ScrollablePanel; import net.sourceforge.kolmafia.swingui.table.IntegerRenderer; import net.sourceforge.kolmafia.swingui.table.ListWrapperTableModel; import net.sourceforge.kolmafia.swingui.widget.AutoFilterTextField; import net.sourceforge.kolmafia.swingui.widget.AutoHighlightTextField; import net.sourceforge.kolmafia.swingui.widget.GenericScrollPane; import net.sourceforge.kolmafia.swingui.widget.ShowDescriptionTable; import net.sourceforge.kolmafia.utilities.InputFieldUtilities; import net.sourceforge.kolmafia.utilities.StringUtilities; public class StoreManageFrame extends GenericPanelFrame { protected static StoreManageFrame INSTANCE = null; private static final JLabel searchLabel = JComponentUtilities.createLabel( "Mall Prices", SwingConstants.CENTER, Color.black, Color.white ); private static final LockableListModel priceSummary = new LockableListModel(); private JComboBox sellingList; protected StoreManageTable manageTable; private JList resultsDisplay; public StoreManageFrame() { super( "Store Manager" ); this.tabs.add( "Price Setup", new StoreManagePanel() ); this.tabs.add( "Additions", new StoreAddPanel() ); this.tabs.add( "Removals", new StoreRemovePanel() ); this.tabs.add( "Store Log", new StoreLogPanel() ); this.setCenterComponent( this.tabs ); StoreManageFrame.INSTANCE = this; StoreManageFrame.updateEarnings( StoreManager.getPotentialEarnings() ); } public static final void cancelTableEditing() { if ( StoreManageFrame.INSTANCE != null ) { InputFieldUtilities.cancelTableEditing( StoreManageFrame.INSTANCE.manageTable ); } } public static final void updateEarnings( final long potentialEarnings ) { if ( StoreManageFrame.INSTANCE == null || GenericFrame.appearsInTab( "StoreManageFrame" ) ) { return; } StoreManageFrame.INSTANCE.setTitle( "Store Manager (potential earnings: " + KoLConstants.COMMA_FORMAT.format( potentialEarnings ) + " meat)" ); } public static void showGlassBox( int rowIndex, int x, int y) { /* * This is a fun way to display a little dialog with a checkbox and a textfield. */ final LimitGlassBox box = new LimitGlassBox( rowIndex ); final JTextField text = new JTextField(); final JCheckBox check = new JCheckBox(); SpringLayout layout = new SpringLayout(); int limit = (Integer) StoreManageFrame.INSTANCE.manageTable.getModel().getValueAt( rowIndex, 4 ); JXPanel panel = new JXPanel( new FlowLayout() ); box.setLayout( layout ); text.setPreferredSize( new Dimension( 100, text.getPreferredSize().height ) ); check.setOpaque( false ); check.setSelected( limit > 0 ); text.setText( String.valueOf( limit ) ); text.setEnabled( limit > 0 ); ActionListener bob = new ActionListener() { public void actionPerformed( ActionEvent e ) { text.setEnabled( check.isSelected() ); if ( text.isEnabled() && text.getText().equals( "0" ) ) { text.setText( "1" ); } if ( !check.isSelected() ) { box.setLimit( 0 ); if ( text.getText().equals( "1" ) ) { text.setText( "0" ); } } else { box.setLimit( StringUtilities.parseInt( text.getText() ) ); } } }; check.addActionListener( bob ); DocumentListener steve = new DocumentListener() { public void insertUpdate( DocumentEvent e ) { this.changedUpdate( e ); } public void removeUpdate( DocumentEvent e ) { this.changedUpdate( e ); } public void changedUpdate( DocumentEvent e ) { try { long lim = StringUtilities.parseLong( e.getDocument().getText( 0, e.getDocument().getLength() ) ); box.setLimit( lim ); } catch ( BadLocationException e1 ) { e1.printStackTrace(); } } }; text.getDocument().addDocumentListener( steve ); panel.add( check ); panel.add( text ); panel.setBorder( BorderFactory.createRaisedBevelBorder() ); box.add( panel ); layout.putConstraint( SpringLayout.WEST, panel, x, SpringLayout.WEST, box ); layout.putConstraint( SpringLayout.NORTH, panel, y, SpringLayout.NORTH, box ); StoreManageFrame.INSTANCE.setGlassPane( box ); box.setVisible( true ); } private class StoreManagePanel extends GenericPanel { public StoreManagePanel() { super( "save prices", "refresh", true ); StoreManageFrame.this.manageTable = new StoreManageTable(); StoreManageFrame.this.manageTable.setEditable( true ); GenericScrollPane manageScroller = new GenericScrollPane( StoreManageFrame.this.manageTable ); JPanel managePanel = new JPanel( new BorderLayout() ); managePanel.add( manageScroller, BorderLayout.CENTER ); JComponentUtilities.setComponentSize( managePanel, 500, 400 ); JPanel storePanel = new JPanel( new BorderLayout() ); storePanel.add( managePanel, BorderLayout.CENTER ); JPanel searchResults = new SearchResultsPanel(); this.setContent( this.elements, true ); this.eastContainer.add( searchResults, BorderLayout.CENTER ); this.container.add( storePanel, BorderLayout.CENTER ); } @Override public void actionConfirmed() { if ( !InputFieldUtilities.finalizeTable( StoreManageFrame.this.manageTable ) ) { return; } KoLmafia.updateDisplay( "Compiling reprice data..." ); int rowCount = StoreManageFrame.this.manageTable.getRowCount(); int[] itemId = new int[ rowCount ]; int[] prices = new int[ rowCount ]; int[] limits = new int[ rowCount ]; SoldItem[] sold = new SoldItem[ StoreManager.getSoldItemList().size() ]; StoreManager.getSoldItemList().toArray( sold ); for ( int i = 0; i < rowCount; ++i ) { String item = (String) StoreManageFrame.this.manageTable.getValueAt( i, 0 ); itemId[ i ] = ItemDatabase.getItemId( item ); prices[ i ] = ( (Integer) StoreManageFrame.this.manageTable.getValueAt( i, 1 ) ).intValue(); int cheapest = ( (Integer) StoreManageFrame.this.manageTable.getValueAt( i, 2 ) ).intValue(); if ( cheapest >= 1000000 && prices[ i ] < cheapest * 0.15 ) { String message = item + ": the price is less than 15% of the cheapest in the mall, continue?"; if ( !InputFieldUtilities.confirm( message ) ) { return; } } int ilim = (Integer) StoreManageFrame.this.manageTable.getValueAt( i, 4 ); limits[ i ] = ilim > 0 ? ilim : 0; } RequestThread.postRequest( new ManageStoreRequest( itemId, prices, limits ) ); } @Override public void actionCancelled() { RequestThread.postRequest( new ManageStoreRequest() ); } } public static final String UNDERCUT_MESSAGE = "KoLmafia will take items priced at 999,999,999 meat and undercut the current lowest price in the mall. " + "Would you like KoLmafia to avoid 'minimum possible prices' (100 meat, or twice the autosell value of the item) when doing so?"; protected class StoreManageTable extends ShowDescriptionTable { public StoreManageTable() { super( StoreManager.getSoldItemList(), 11, 7 ); this.setColumnClasses( new Class[] { String.class, Integer.class, Integer.class, Integer.class, Boolean.class, JButton.class, JButton.class, } ); this.setModel( new StoreManageTableModel() ); doColumnSetup(); setEditors(); setRenderers(); setHighlighters(); } private void doColumnSetup() { this.getColumnModel().getColumn( 6 ).setPreferredWidth( 44 ); this.getColumnModel().getColumn( 6 ).setResizable( false ); this.getColumnModel().getColumn( 5 ).setPreferredWidth( 44 ); this.getColumnModel().getColumn( 5 ).setResizable( false ); this.getColumnModel().getColumn( 4 ).setPreferredWidth( 44 ); this.getColumnModel().getColumn( 4 ).setResizable( false ); this.getColumnModel().getColumn( 3 ).setResizable( false ); this.getColumnModel().getColumn( 0 ).setPreferredWidth( 220 ); this.getColumnModel().getColumn( 1 ).setPreferredWidth( 100 ); this.getTableHeader().setReorderingAllowed( false ); this.setAutoResizeMode( AUTO_RESIZE_NEXT_COLUMN ); this.setIntercellSpacing( new Dimension(1,1) ); } private void setEditors() { this.setDefaultEditor( JButton.class, new JButtonHackEditor() ); this.setDefaultEditor( Boolean.class, new JButtonHackEditor() ); this.setDefaultEditor( Integer.class, new PriceEditor() ); } private void setRenderers() { this.setDefaultRenderer( Boolean.class, new BoolRenderer() ); IntegerRenderer rend = new IntegerRenderer(); rend.setHorizontalAlignment( JLabel.RIGHT ); this.setDefaultRenderer( Integer.class, rend ); this.setDefaultRenderer( String.class, new DefaultTableRenderer() ); } private void setHighlighters() { Highlighter stripe = HighlighterFactory.createSimpleStriping(); this.addHighlighter( stripe ); HighlightPredicate mouseOver = new HighlightPredicate() { public boolean isHighlighted( Component renderer, ComponentAdapter adapter ) { if ( !adapter.getComponent().isEnabled() ) return false; Point p = (Point) adapter.getComponent().getClientProperty( RolloverProducer.ROLLOVER_KEY ); return p != null && p.y == adapter.row && convertColumnIndexToModel( p.x ) == 1 && convertColumnIndexToModel( adapter.column ) == 1; } }; HighlightPredicate valueChanged = new HighlightPredicate() { public boolean isHighlighted( Component renderer, ComponentAdapter adapter ) { if ( !adapter.getComponent().isEnabled() ) return false; if ( convertColumnIndexToModel( adapter.column ) == 1 ) { int cellValue = (Integer) adapter.getValueAt( convertRowIndexToModel( adapter.row ), convertColumnIndexToModel( adapter.column ) ); SoldItem it = ( (StoreManageTableModel) StoreManageTable.this.getModel() ).getSoldItem( convertRowIndexToModel( adapter.row ) ); return it != null && cellValue != it.getPrice(); } if ( convertColumnIndexToModel( adapter.column ) == 4 ) { int cellValue = (Integer) adapter.getValueAt( convertRowIndexToModel( adapter.row ), convertColumnIndexToModel( adapter.column ) ); SoldItem it = ( (StoreManageTableModel) StoreManageTable.this.getModel() ).getSoldItem( convertRowIndexToModel( adapter.row ) ); return it != null && cellValue != it.getLimit(); } return false; } }; HighlightPredicate warning = new HighlightPredicate() { public boolean isHighlighted( Component renderer, ComponentAdapter adapter ) { if ( !adapter.getComponent().isEnabled() ) return false; if ( convertColumnIndexToModel( adapter.column ) != 1 ) return false; int cellValue = (Integer) adapter.getValueAt( convertRowIndexToModel( adapter.row ), convertColumnIndexToModel( adapter.column ) ); SoldItem it = ( (StoreManageTableModel) StoreManageTable.this.getModel() ).getSoldItem( convertRowIndexToModel( adapter.row ) ); return it != null && (cellValue < it.getLowest() * 0.15) && it.getLowest() > 50000; } }; HighlightPredicate auto = new HighlightPredicate() { public boolean isHighlighted( Component renderer, ComponentAdapter adapter ) { if ( !adapter.getComponent().isEnabled() ) return false; if ( convertColumnIndexToModel( adapter.column ) != 0 ) return false; int cellValue = (Integer) adapter.getValueAt( convertRowIndexToModel( adapter.row ), 1 ); return (cellValue == 999999999); } }; AbstractHighlighter bold = new AbstractHighlighter( auto ) { private Font BOLD_FONT; @Override protected Component doHighlight( Component renderer, ComponentAdapter adapter ) { if ( adapter.isSelected() ) { renderer.setForeground( getSelectionForeground() ); } else { renderer.setForeground( getForeground() ); } if ( BOLD_FONT == null ) { BOLD_FONT = renderer.getFont().deriveFont( Font.BOLD ); } renderer.setFont( BOLD_FONT ); return renderer; } }; AbstractHighlighter underline = new AbstractHighlighter( mouseOver ) { private Font UNDERLINE_FONT; @Override protected Component doHighlight( Component renderer, ComponentAdapter adapter ) { if ( adapter.isSelected() ) { renderer.setForeground( getSelectionForeground() ); } else { renderer.setForeground( getForeground() ); } if ( UNDERLINE_FONT == null ) { Map<TextAttribute, Integer> fontAttributes = new HashMap<TextAttribute, Integer>(); fontAttributes.put( TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON ); UNDERLINE_FONT = renderer.getFont().deriveFont( fontAttributes ); } renderer.setFont( UNDERLINE_FONT ); return renderer; } }; ColorHighlighter mouse = new ColorHighlighter( mouseOver ); mouse.setForeground( Color.blue ); ColorHighlighter change = new ColorHighlighter( valueChanged ); change.setBackground( new Color( 0xB5EAAA ) ); change.setSelectedBackground( new Color( 0x306754 ) ); CompoundHighlighter comp = new CompoundHighlighter( underline, mouse ); ColorHighlighter warn = new ColorHighlighter( warning ); warn.setBackground( Color.red ); warn.setSelectedBackground( Color.red ); this.addHighlighter( bold ); this.addHighlighter( change ); this.addHighlighter( comp ); this.addHighlighter( warn ); } @Override public boolean isCellEditable( final int row, final int col ) { int column = convertColumnIndexToModel( col ); if ( column == 1 || column == 4 || column == 5 || column == 6 ) { return true; } return false; } private class JButtonHackEditor implements TableCellEditor { /* * This is an awful, horrible hack, but swing doesn't provide many options otherwise. Since JTables do not * forward MouseEvents to embedded components, we have to hack around it - override the editor and take * advantage of the fact that it knows what cell is trying to be edited. The other way to do this is to * install a mouselistener on the table that converts all mouseevents to row/column coordinates and then * passes a mouse event to that cell. I find that has way more overhead and is less robust than doing it * this way. Sigh. */ public Object getCellEditorValue() { return null; } public boolean isCellEditable( EventObject anEvent ) { return true; } public boolean shouldSelectCell( EventObject anEvent ) { return false; } public boolean stopCellEditing() { return false; } public void cancelCellEditing() { } public void addCellEditorListener( CellEditorListener l ) { } public void removeCellEditorListener( CellEditorListener l ) { } public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column ) { if ( value instanceof Boolean || value instanceof Integer ) { Rectangle rect = table.getCellRect( row, column, false ); // Look at this nonsense Point p = new Point( rect.x, rect.y ); // I hate you Swing SwingUtilities.convertPointToScreen( p, table ); // I mean seriously, WTF SwingUtilities.convertPointFromScreen( p, StoreManageFrame.INSTANCE.getContentPane() ); StoreManageFrame.showGlassBox( convertRowIndexToModel( row ), p.x + rect.width / 2 - 15, p.y + 13 ); } else if ( value instanceof JButton ) { ( (JButton) value ).doClick( 10 ); } return null; } } } private class StoreManageTableModel extends ListWrapperTableModel { public StoreManageTableModel() { super( new String[] { "Item Name", "Price", "Lowest", "Qty", "Lim", " ", " " }, new Class[] { String.class, Integer.class, Integer.class, Integer.class, Boolean.class, JButton.class, JButton.class }, new boolean[] { false, true, false, false, true, false, false }, StoreManager.getSoldItemList() ); } @Override public Vector<Serializable> constructVector( final Object o ) { Vector<Serializable> value = (Vector<Serializable>) o; if ( value.size() < 7 ) { String itemName = (String) value.get( 0 ); String displayName = StringUtilities.getDisplayName( itemName ); value.set( 0, displayName ); JButton removeSomeButton = new JButton( JComponentUtilities.getImage( "xgray.gif" ) ); removeSomeButton.setToolTipText( "remove some of item from store" ); removeSomeButton.addActionListener( new RemoveSomeListener( value ) ); JComponentUtilities.setComponentSize( removeSomeButton, new Dimension( 20, 20 ) ); value.add( removeSomeButton ); JButton searchItemButton = new JButton( JComponentUtilities.getImage( "forward.gif" ) ); searchItemButton.setToolTipText( "price analysis" ); searchItemButton.addActionListener( new SearchItemListener( itemName ) ); value.add( searchItemButton ); } return value; } public SoldItem getSoldItem( int row ) { return (SoldItem) this.listModel.get( row ); } } private class SearchItemListener extends ThreadedListener { private final String itemName; public SearchItemListener( final String itemName ) { this.itemName = itemName; } @Override protected void execute() { String searchName = this.itemName; if ( searchName == null ) { AdventureResult item = (AdventureResult) StoreManageFrame.this.sellingList.getSelectedItem(); if ( item == null ) { return; } searchName = item.getName(); } StoreManageFrame.searchLabel.setText( searchName ); StoreManager.searchMall( "\"" + searchName + "\"", 10, StoreManageFrame.priceSummary ); KoLmafia.updateDisplay( "Price analysis complete." ); } } private class RemoveSomeListener extends ThreadedListener { private final Vector<Serializable> vector; private final int itemId; public RemoveSomeListener( Vector<Serializable> vector ) { this.vector = vector; String itemName = (String) vector.get( 0 ); this.itemId = ItemDatabase.getItemId( itemName ); } @Override protected void execute() { int max = (Integer) this.vector.get( 3 ); Integer val = InputFieldUtilities.getQuantity( "Remove how many?", max, max ); if ( val != null ) { int qty = val.intValue(); if ( qty > 0 ) { RequestThread.postRequest( new ManageStoreRequest( this.itemId, qty ) ); } } } } private class StoreAddPanel extends JTabbedPane { public StoreAddPanel() { super( JTabbedPane.LEFT ); this.addTab( "Inventory", new StoreAddFromInventoryPanel() ); this.addTab( "Storage", new StoreAddFromStoragePanel() ); } } private class StoreAddFromInventoryPanel extends ItemListManagePanel { public StoreAddFromInventoryPanel() { super( "mallsell", "autosell", (SortedListModel<AdventureResult>) KoLConstants.inventory ); this.addFilters(); this.filters[ 4 ].setSelected( false ); this.filters[ 4 ].setEnabled( false ); this.filterItems(); } @Override public void actionConfirmed() { AdventureResult[] items = this.getDesiredItems( "Mallsell" ); if ( items == null ) { return; } RequestThread.postRequest( new AutoMallRequest( items ) ); RequestThread.postRequest( new ManageStoreRequest() ); } @Override public void actionCancelled() { AdventureResult[] items = this.getDesiredItems( "Autosell" ); if ( items == null ) { return; } RequestThread.postRequest( new AutoSellRequest( items ) ); } } private class StoreAddFromStoragePanel extends ItemListManagePanel { public StoreAddFromStoragePanel() { super( "mallsell", null, (SortedListModel<AdventureResult>) KoLConstants.storage, true, true ); this.addFilters(); this.filters[ 4 ].setSelected( false ); this.filters[ 4 ].setEnabled( false ); this.filterItems(); } @Override public void actionConfirmed() { AdventureResult[] items = this.getDesiredItems( "Mallsell" ); if ( items == null ) { return; } RequestThread.postRequest( new ManageStoreRequest( items, true ) ); RequestThread.postRequest( new ManageStoreRequest() ); } @Override public void actionCancelled() { } } private class StoreRemovePanel extends ItemListManagePanel { public StoreRemovePanel() { super( "take all", "take one", StoreManager.getSortedSoldItemList() ); this.addFilters(); this.filters[ 4 ].setSelected( false ); this.filters[ 4 ].setEnabled( false ); } @Override public void actionConfirmed() { this.removeItems( true ); } @Override public void actionCancelled() { this.removeItems( false ); } public void removeItems( final boolean takeAll ) { StoreManageFrame.cancelTableEditing(); Object[] items = this.getElementList().getSelectedValues(); for ( int i = 0; i < items.length; ++i ) { SoldItem soldItem = ( (SoldItem) items[ i ] ); int count = takeAll ? soldItem.getQuantity() : 1; RequestThread.postRequest( new ManageStoreRequest( soldItem.getItemId(), count ) ); } RequestThread.postRequest( new ManageStoreRequest() ); } } /** * An internal class which represents the panel used for tallying the results of the mall search request. Note that * all of the tallying functionality is handled by the <code>LockableListModel</code> provided, so this functions * as a container for that list model. */ private class SearchResultsPanel extends JPanel { public SearchResultsPanel() { super( new BorderLayout() ); JPanel container = new JPanel( new BorderLayout() ); container.setBorder( BorderFactory.createLineBorder( Color.black, 1 ) ); container.add( StoreManageFrame.searchLabel, BorderLayout.NORTH ); JComponentUtilities.setComponentSize( StoreManageFrame.searchLabel, 150, 16 ); StoreManageFrame.this.resultsDisplay = new JList( StoreManageFrame.priceSummary ); StoreManageFrame.this.resultsDisplay.setPrototypeCellValue( "1234567890ABCDEF" ); StoreManageFrame.this.resultsDisplay.setVisibleRowCount( 11 ); StoreManageFrame.this.resultsDisplay.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION ); GenericScrollPane scrollArea = new GenericScrollPane( StoreManageFrame.this.resultsDisplay ); container.add( scrollArea, BorderLayout.CENTER ); this.add( Box.createVerticalStrut( 20 ), BorderLayout.NORTH ); this.add( container, BorderLayout.CENTER ); } } private class StoreLogPanel extends ScrollablePanel { public StoreLogPanel() { super( "", "refresh", "resort", new JList( StoreManager.getStoreLog()), false ); JPanel northPanel = new JPanel( new BorderLayout() ); this.actualPanel.add( northPanel, BorderLayout.NORTH ); AutoFilterTextField filterfield = new AutoFilterTextField( (JList) this.scrollComponent ); this.centerPanel.add( filterfield, BorderLayout.NORTH ); } @Override public void actionConfirmed() { StoreManager.getStoreLog().clear(); RequestThread.postRequest( new ManageStoreRequest( true ) ); } @Override public void actionCancelled() { StoreManager.sortStoreLog( true ); } } public class BoolRenderer extends JCheckBox implements TableCellRenderer { public BoolRenderer() { setHorizontalAlignment( JLabel.CENTER ); } public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) { if ( isSelected ) { setForeground( table.getSelectionForeground() ); //super.setBackground(table.getSelectionBackground()); setBackground( table.getSelectionBackground() ); } else { setForeground( table.getForeground() ); setBackground( table.getBackground() ); } setSelected( ( value != null && ( (Integer) value ) > 0 ) ); return this; } } private static class PriceEditor extends DefaultCellEditor { private static final AutoHighlightTextField rightField = new AutoHighlightTextField() { @Override public int getHorizontalAlignment() { return JLabel.RIGHT; } }; public PriceEditor() { this( rightField ); } public PriceEditor( JTextField textField ) { super( textField ); } @Override public Object getCellEditorValue() { return StringUtilities.parseInt( super.getCellEditorValue().toString() ); } @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column ) { if ( value == null ) { return super.getTableCellEditorComponent( table, value, isSelected, row, column ); } ( (JTextField) this.editorComponent ).setText( KoLConstants.COMMA_FORMAT.format( value ) ); return this.editorComponent; } } } class LimitGlassBox extends JXGlassBox { private long limit; private int rowIndex; public LimitGlassBox( int rowIndex ) { super(1.0f); this.rowIndex = rowIndex; this.limit = (Integer) StoreManageFrame.INSTANCE.manageTable.getModel().getValueAt( rowIndex, 4 ); } public void setLimit( long lim ) { this.limit = lim; } @Override public void dismiss() { StoreManageFrame.INSTANCE.manageTable.getModel().setValueAt( (int)limit, rowIndex, 4 ); super.dismiss(); } };