package com.towel.swing.table;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.TableModel;
import com.towel.cfg.TowelConfig;
import com.towel.collections.paginator.ListPaginator;
import com.towel.collections.paginator.Paginator;
import com.towel.io.Closable;
import com.towel.swing.ModalWindow;
import com.towel.swing.event.ObjectSelectListener;
import com.towel.swing.event.SelectEvent;
public class SelectTable<T> {
private static final String CLOSE_TXT_ATTR = "close_txt_attr";
private static final String SELECT_TXT_ATTR = "select_txt_attr";
private List<ObjectSelectListener> listeners;
private JTable table;
private Paginator<T> data;
private ObjectTableModel<T> model;
private JFrame frame;
private JPanel content;
private JButton selectButton, closeButton;
private JLabel pageLabel;
private List<Closable> closableHook;
private TableFilter filter;
public static final int SINGLE = 0;
public static final int LIST = 1;
private int selectType;
public SelectTable(ObjectTableModel<T> model2, List<T> list2) {
this(model2, new ListPaginator<T>(list2), SINGLE);
}
public SelectTable(ObjectTableModel<T> model2, Paginator<T> list2) {
this(model2, list2, SINGLE);
}
public SelectTable(ObjectTableModel<T> model, Paginator<T> list,
int selectType) {
listeners = new ArrayList<ObjectSelectListener>();
closableHook = new ArrayList<Closable>();
model.setEditableDefault(false);
data = list;
this.model = model;
model.setData(data.nextResult());
buildBody();
selectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
try {
updateSelectedObject();
} catch (Exception e) {
e.printStackTrace();
}
dispose();
}
});
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
table.addMouseListener(new SelectionListener());
setSelectionType(selectType);
setLocale(TowelConfig.getInstance().getDefaultLocale());
}
public void useTableFilter() {
filter = new TableFilter(table);
filter.setLocale(TowelConfig.getInstance().getDefaultLocale());
}
private void buildBody() {
table = new JTable(model);
frame = new JFrame("Select");
content = new JPanel();
pane = new JScrollPane();
pane.setViewportView(table);
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
content.add(pane);
content.add(getResultScrollPane());
content.add(createCommandButtons());
}
private JPanel createCommandButtons() {
JPanel buttons = new JPanel();
buttons.setAlignmentX(.5f);
selectButton = new JButton("Select");
closeButton = new JButton("Close");
buttons.add(selectButton);
buttons.add(closeButton);
return buttons;
}
public void setSize(int width, int height) {
pane.setPreferredSize(new Dimension(width, height));
pane.setMinimumSize(new Dimension(width, height));
}
public JTable getTable() {
return table;
}
public void closeOnDispose(Closable close) {
closableHook.add(close);
}
private boolean closed = false;
private JScrollPane pane;
public void close() {
if (closed)
return;
closed = true;
for (Closable closable : closableHook)
closable.close();
}
public void setSelectButtonText(String text) {
selectButton.setText(text);
}
public void setCloseButtonText(String text) {
closeButton.setText(text);
}
public void setLocale(Locale locale) {
InputStream is = getClass().getResourceAsStream(
"/res/strings_" + locale.toString() + ".properties");
Properties props = new Properties();
try {
props.load(is);
is.close();
setOptions(props);
} catch (IOException e) {
e.printStackTrace();
}
}
private void setOptions(Properties props) {
setSelectButtonText(props.getProperty(SELECT_TXT_ATTR));
setCloseButtonText(props.getProperty(CLOSE_TXT_ATTR));
}
public void setButtonsText(String select, String close) {
setSelectButtonText(select);
setCloseButtonText(close);
}
public void addObjectSelectListener(ObjectSelectListener listener) {
listeners.add(listener);
}
public Container getContent() {
return content;
}
public void showModal(Component parent) {
try {
final JDialog dialog = ModalWindow.createDialog(parent,
getContent(), "Select");
closeOnDispose(new Closable() {
@Override
public void close() {
dialog.dispose();
}
});
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
public void showSelectTable() {
showSelectTable("Select");
}
public void showSelectTable(String title) {
frame = new JFrame(title);
frame.setContentPane(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(2);
frame.setVisible(true);
closeOnDispose(new Closable() {
@Override
public void close() {
frame.dispose();
}
});
}
private void notifyListeners(SelectEvent evt) {
for (ObjectSelectListener listener : listeners)
listener.notifyObjectSelected(evt.clone());
}
public void setSelectionType(int selectType) {
this.selectType = selectType;
table.setSelectionMode(this.selectType == SINGLE ? ListSelectionModel.SINGLE_SELECTION
: ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
public int getSelectType() {
return selectType;
}
public void dispose() {
close();
if (frame != null) {
frame.dispose();
}
}
public JPanel getResultScrollPane() {
JPanel container = new JPanel();
pageLabel = new JLabel((new StringBuilder("1/")).append(
data.getMaxPage() + 1).toString());
JButton first = new JButton("<<");
JButton previous = new JButton("<");
JButton next = new JButton(">");
JButton last = new JButton(">>");
container.add(first);
container.add(previous);
container.add(pageLabel);
container.add(next);
container.add(last);
first.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
firstResult();
}
});
previous.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
previousResult();
}
});
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
nextResult();
}
});
last.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lastResult();
}
});
return container;
}
private void firstResult() {
data.setCurrentPage(0);
model.setData(data.nextResult());
pageLabel.setText((new StringBuilder("1/")).append(
data.getMaxPage() + 1).toString());
}
private void previousResult() {
if (data.getCurrentPage() - 2 < 0) {
return;
} else {
data.setCurrentPage(data.getCurrentPage() - 2);
model.setData(data.nextResult());
pageLabel.setText((new StringBuilder(String.valueOf(String
.valueOf(data.getCurrentPage())))).append("/")
.append(data.getMaxPage() + 1).toString());
return;
}
}
private void nextResult() {
try {
if (data.getCurrentPage() >= data.getMaxPage()) {
data.setCurrentPage(data.getMaxPage());
}
model.setData(data.nextResult());
pageLabel.setText((new StringBuilder(String.valueOf(String
.valueOf(data.getCurrentPage())))).append("/")
.append(data.getMaxPage() + 1).toString());
} catch (Exception e) {
return;
}
}
private void lastResult() {
data.setCurrentPage(data.getMaxPage());
model.setData(data.nextResult());
pageLabel.setText((new StringBuilder(String.valueOf(String.valueOf(data
.getCurrentPage())))).append("/").append(data.getMaxPage() + 1)
.toString());
}
public void updateSelectedObject() {
int[] objIndex = table.getSelectedRows();
int[] realIdx = filter == null ? objIndex : filter
.getModelRows(objIndex);
if (objIndex.length == 1)
notifyListeners(new SelectEvent(this, model.getValue(realIdx[0])));
else {
List<T> selected = new ArrayList<T>();
for (int i : realIdx)
selected.add(model.getValue(i));
notifyListeners(new SelectEvent(this, selected));
}
dispose();
}
public void notifyDataChanged() {
model.fireTableDataChanged();
}
private class SelectionListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
updateSelectedObject();
dispose();
}
}
}
public TableModel getModel() {
return model;
}
public void setFont(Font font) {
table.setFont(font);
}
public void fitColumnsToHeader() {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
Resizer.fitColumnsByHeader(0, table);
}
}