package android.app;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.PrintWriter;
import java.io.Writer;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.database.Cursor;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.TextView;
import static com.applang.Util.*;
import static com.applang.Util1.*;
import static com.applang.Util2.*;
import static com.applang.SwingUtil.*;
public class AlertDialog extends Dialog implements DialogInterface
{
public static int behavior = Behavior.MODAL;
public AlertDialog(Frame owner,
String title, String caption,
Object message,
int optionType, int behavior,
Icon icon,
Job<Void> followUp, Object...params)
{
super(owner, behavior);
setTitle(title);
this.optionType = optionType;
this.options = defaultOptions(optionType);
this.followUp = followUp;
this.params = params;
if (icon == null)
icon = defaultIcon(optionType);
init(caption, icon, message);
}
int optionType = JOptionPane.DEFAULT_OPTION;
ValList options = vlist();
Job<Void> followUp;
Object[] params;
private void init(String caption, Icon icon, Object message) {
JPanel contentPane = new JPanel(new BorderLayout(12,12));
contentPane.setBorder(new EmptyBorder(12,12,12,12));
setContentPane(contentPane);
Box iconBox = new Box(BoxLayout.Y_AXIS);
iconBox.add(new JLabel(icon));
iconBox.add(Box.createGlue());
contentPane.add(BorderLayout.WEST,iconBox);
JPanel centerPanel = new JPanel(new BorderLayout(6,6));
centerPanel.add(BorderLayout.NORTH,
new JLabel(htmlize(caption)));
if (message instanceof Component)
centerPanel.add(BorderLayout.CENTER, (Component)message);
else {
JTextArea textArea = new JTextArea(10, 80);
textArea.setText(stringValueOf(message));
textArea.setLineWrap(true);
textArea.setCaretPosition(0);
centerPanel.add(BorderLayout.CENTER, new JScrollPane(textArea));
}
contentPane.add(BorderLayout.CENTER,centerPanel);
Box box = new Box(BoxLayout.X_AXIS);
JButton btn = null;
for (int i = 0; i < options.size() - 1; i++) {
btn = addButton(i, box);
}
box.add(Box.createGlue());
contentPane.add(BorderLayout.SOUTH,box);
switch (optionType) {
case 5:
result = 4;
break;
default:
result = JOptionPane.CANCEL_OPTION;
break;
}
if (btn != null)
getRootPane().setDefaultButton(btn);
pack();
setLocationRelativeTo(getParent());
}
private JButton addButton(int index, Box box) {
box.add(Box.createGlue());
JButton btn = new JButton(stringValueOf(options.get(index)));
btn.addActionListener(new ActionHandler());
box.add(btn);
return btn;
}
class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
String cmd = evt.getActionCommand();
if (stringValueOf(options.get(0)).equals(cmd)) {
ok();
return;
}
result = options.indexOf(cmd);
if (optionType == 5 && getResult() == 1) {
ok();
result = 1;
return;
}
cancel();
}
}
// called if enter key pressed
public void ok() {
if (viewGroup == null) {
result = JOptionPane.OK_OPTION;
if (followUp != null)
try {
followUp.perform(null, params);
} catch (Exception e) {
Log.e(TAG, "followUp", e);
}
}
else {
JButton btn = null;
Container contentPane = getContentPane();
if (contentPane instanceof JOptionPane) {
JOptionPane optionPane = (JOptionPane) contentPane;
Object[] options = optionPane.getOptions();
Component focused = KeyboardFocusManager
.getCurrentKeyboardFocusManager().getFocusOwner();
int index = arrayindexof(focused, options);
if (index > -1)
btn = (JButton) options[index];
else {
Object option = optionPane.getInitialValue();
if (option instanceof JButton)
btn = (JButton) option;
}
}
if (btn != null)
btn.doClick();
}
cancel();
}
// called if escape key pressed
public void cancel() {
if (viewGroup != null)
dismiss();
else
dispose();
}
public AlertDialog(Context context, int behavior) {
super(null, behavior);
viewGroup = new ViewGroup(context);
setEnterEnabled(false);
}
ViewGroup viewGroup = null;
public View findViewById(int id) {
return viewGroup.findViewById(id);
}
@SuppressWarnings("unchecked")
public <T extends JComponent> T findComponentById(int id, Object...names) {
View vw = findViewById(id);
if (vw == null)
return null;
Container comp = (Container) vw.getComponent();
ValList list = vlist(names);
while (comp != null && list.size() > 0) {
comp = findFirstComponent(comp, stringValueOf(list.get(0)));
list.remove(0);
}
return (T)comp;
}
@SuppressWarnings("resource")
public Writer feed(int id) {
final TextView tv = (TextView) findViewById(id);
try {
if (tv != null) {
PipedWriter writer = new PipedWriter();
final PipedReader reader = new PipedReader(writer);
Runnable r = new Runnable() {
public void run() {
try {
BufferedReader br = new BufferedReader(reader);
String line = null;
while((line = br.readLine()) != null)
{
synchronized (tv) {
tv.append(line + NEWLINE);
}
}
br.close();
}
catch (Exception e) {
Log.e(TAG, "feed", e);
}
}
};
new Thread(r).start();
return writer;
}
} catch (Exception e) {
Log.e(TAG, "feed", e);
}
return null;
}
public static class Builder
{
AlertDialog dialog;
Resources res;
JOptionPane optionPane;
public Builder(Context context, Object...params) {
dialog = new AlertDialog(context, param_Integer(behavior, 0, params));
res = context.getResources();
optionPane = new JOptionPane();
int optionType = param_Integer(JOptionPane.DEFAULT_OPTION - 1, 1, params);
if (optionType >= JOptionPane.DEFAULT_OPTION) {
ValList list = defaultOptions(optionType);
for (int i = 0; i < list.size() - 1; i++) {
String option = stringValueOf(list.get(i));
addOption(-1-i, option, new OnClickListener() {
public void onClick(DialogInterface dlg, int which) {
dialog.result = which;
dlg.dismiss();
}
});
}
int which = list.indexOf(list.get(-1));
while (which > -1 && nullOrEmpty(list.get(which)))
which--;
setInitialOption(which);
dialog.result = which;
}
}
public AlertDialog dialog() {
return dialog;
}
String title = "";
public AlertDialog create() {
ViewGroup vg = dialog.viewGroup;
Container container = ViewGroup.build(vg, true);
if (dialog.options.size() > 0) {
if (vg.getChildCount() > 0) {
if (vg.getChildCount() < 2)
container = (Container) vg.getChildAt(0).getComponent();
optionPane.setMessage(container);
}
optionPane.setOptions(dialog.options.toArray());
dialog.setContentPane(optionPane);
}
else {
for (int i = 0; i < container.getComponentCount(); i++) {
Component component = container.getComponent(i);
dialog.getContentPane().add(component);
}
}
dialog.setTitle(title);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
return dialog;
}
public void addView(View view, LayoutParams params) {
dialog.viewGroup.addView(view, params);
}
public Builder setCancelable(boolean b) {
return this;
}
public Builder setOnCancelListener(final OnCancelListener onCancelListener) {
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
onCancelListener.onCancel(dialog);
}
});
return this;
}
public Builder setIcon(int iconId) {
if (iconId > 0) {
ImageIcon icon = iconFrom("/images/spinner.gif");
return setIcon(icon);
}
return this;
}
public Builder setIcon(Icon icon) {
optionPane.setIcon(icon);
return this;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setInitialOption(int option) {
if (option < 0)
option = -option - 1;
if (option < dialog.options.size())
optionPane.setInitialValue(dialog.options.get(option));
return this;
}
public Builder setMessage(CharSequence message) {
addView(new View(new JLabel(message.toString())), null);
return this;
}
private void addOption(final int which, String string, final OnClickListener onClickListener) {
final JButton btn = new JButton(string);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.result = btn.getText();
if (onClickListener != null)
onClickListener.onClick(dialog, which < 0 ? -which - 1 : which);
}
});
dialog.options.add(btn);
if (which == DialogInterface.BUTTON_NEGATIVE) {
setInitialOption(dialog.options.indexOf(btn));
dialog.setEnterEnabled(true);
}
}
public Builder setPositiveButton(String string, OnClickListener onClickListener) {
addOption(DialogInterface.BUTTON_POSITIVE, string, onClickListener);
return this;
}
public Builder setPositiveButton(int id, OnClickListener onClickListener) {
String string = res.getString(id);
addOption(DialogInterface.BUTTON_POSITIVE, string, onClickListener);
return this;
}
public Builder setNegativeButton(String string, OnClickListener onClickListener) {
addOption(DialogInterface.BUTTON_NEGATIVE, string, onClickListener);
return this;
}
public Builder setNegativeButton(int id, OnClickListener onClickListener) {
String string = res.getString(id);
addOption(DialogInterface.BUTTON_NEGATIVE, string, onClickListener);
return this;
}
public Builder setNeutralButton(String string, OnClickListener onClickListener) {
addOption(DialogInterface.BUTTON_NEUTRAL, string, onClickListener);
return this;
}
public Builder setNeutralButton(int id, OnClickListener onClickListener) {
String string = res.getString(id);
addOption(DialogInterface.BUTTON_NEUTRAL, string, onClickListener);
return this;
}
public Builder setView(JComponent component) {
return setView(new View(component));
}
public Builder setView(View view) {
view.setId(1);
if (view instanceof ViewGroup)
iterateViews((ViewGroup)view, 0,
new Function<Object[]>() {
public Object[] apply(Object... params) {
View v = param(null, 0, params);
addView(v, null);
return param(null, 2, params);
}
}
);
else
addView(view, null);
return this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public Builder setItems(final CharSequence[] items, final OnClickListener listener) {
final JList list = new JList(defaultListModel(asList(items)));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent ev) {
dialog.result = list.getSelectedValue();
final int which = list.getSelectedIndex();
list.setSelectedIndex(which);
switch (ev.getClickCount()) {
case 1:
new Task<Void>(null, new Job<Void>() {
public void perform(Void t, Object[] params) throws Exception {
listener.onClick(dialog, which);
}
}, 500).execute();
break;
case 2:
listener.onClick(dialog, -which - 1);
break;
}
}
});
list.setName("list");
addView(new View(new JScrollPane(list)).setId(1), null);
return this;
}
public Builder setSingleChoiceItems(final CharSequence[] items, int checkedItem, final OnClickListener onClickListener) {
final JTable table = new JTable(new AbstractTableModel() {
@Override
public int getRowCount() {
return items.length;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return items[rowIndex];
}
});
table.setTableHeader(null);
ListSelectionModel listSelectionModel = table.getSelectionModel();
listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
int which = table.getSelectedRow();
onClickListener.onClick(dialog, which);
}
});
table.setSelectionModel(listSelectionModel);
if (checkedItem > -1 && checkedItem < table.getModel().getRowCount())
table.setRowSelectionInterval(checkedItem, checkedItem);
addView(new View(scrollableViewport(table)).setId(1), null);
return this;
}
public Builder setMultiChoiceItems(final CharSequence[] items, final boolean[] checkedItems, final OnMultiChoiceClickListener onClickListener) {
final JTable table = new JTable(new AbstractTableModel() {
@Override
public int getRowCount() {
return items.length;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return columnIndex < 1 ?
items[rowIndex] :
checkedItems[rowIndex];
}
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return col == 1;
}
@Override
public void setValueAt(Object value, int row, int col) {
if (col == 1)
checkedItems[row] = (Boolean) value;
}
});
table.setTableHeader(null);
ListSelectionModel listSelectionModel = table.getSelectionModel();
listSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
int which = table.getSelectedRow();
onClickListener.onClick(dialog, which, checkedItems[which]);
}
});
table.setSelectionModel(listSelectionModel);
addView(new View(scrollableViewport(table)).setId(1), null);
return this;
}
public Builder setSingleChoiceItems(Cursor cursor, int checkedItem, String labelColumn, final OnClickListener listener) {
// TODO Auto-generated method stub
return this;
}
public Builder setMultiChoiceItems(Cursor cursor, String isCheckedColumn, String labelColumn, final OnMultiChoiceClickListener listener) {
// TODO Auto-generated method stub
return this;
}
}
public static void alerter(Context context, String title, Exception ex) {
EditText et = new EditText(context,
Resources.attributeSet(context, "android:inputType=\"textMultiLine\"", "readOnly=\"true\""));
int id = 1;
et.setId(id);
et.getComponent().setPreferredSize(new Dimension(800,400));
AlertDialog dlg = new AlertDialog.Builder(context)
.setTitle(title)
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))
.setView(et)
.setNeutralButton(stringValueOf(defaultOptions(3).get(0)), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
})
.create();
try {
Writer out = dlg.feed(id);
ex.printStackTrace(new PrintWriter(out));
out.close();
} catch (Exception e) {
Log.e(TAG, "alerter", e);
}
dlg.open();
}
@SuppressWarnings("rawtypes")
public static String chooser(Context context, String title, String[] values, String...defaults) {
final AlertDialog dlg = new Builder(context)
.setTitle(title)
.setItems(values, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
}
})
.create();
if (isAvailable(0, defaults)) {
JList list = dlg.findComponentById(1, "list");
list.setSelectedValue(defaults[0], true);
}
dlg.open();
return (String) dlg.result;
}
}