View Javadoc
1   package com.github.celldynamics.quimp;
2   
3   import java.awt.Color;
4   import java.awt.Font;
5   import java.awt.GridLayout;
6   import java.awt.Rectangle;
7   import java.awt.Window;
8   import java.awt.event.ActionEvent;
9   import java.awt.event.ActionListener;
10  import java.awt.event.MouseAdapter;
11  import java.awt.event.MouseEvent;
12  import java.awt.event.MouseListener;
13  import java.awt.event.WindowAdapter;
14  import java.awt.event.WindowEvent;
15  
16  import javax.swing.JDialog;
17  import javax.swing.JFrame;
18  import javax.swing.JMenu;
19  import javax.swing.JMenuBar;
20  import javax.swing.JMenuItem;
21  import javax.swing.JPanel;
22  import javax.swing.JPopupMenu;
23  import javax.swing.JScrollPane;
24  import javax.swing.JTextArea;
25  
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  /**
30   * Build About dialog with support of mouse operations.
31   * 
32   * <p>It can be used as universal text displayer.
33   * 
34   * @author p.baniukiewicz
35   *
36   */
37  public class AboutDialog implements ActionListener {
38    private static final Logger LOGGER = LoggerFactory.getLogger(AboutDialog.class.getName());
39    /**
40     * About window.
41     */
42    public JDialog aboutWnd;
43    private JTextArea info; // text area field
44    private JPopupMenu popup; // popup menu
45    private JMenuBar mbar; // the same but in menu bar
46    /**
47     * Number of rows in window.
48     */
49    private int rows = 30;
50    /**
51     * Number of columns in window.
52     */
53    private int cols = 80;
54    private final String limiter = "-"; // Limiter char
55  
56    /**
57     * Build window and menus with given size.
58     * 
59     * @param owner Owner of Dialog.
60     * @param rows Number of rows.
61     * @param cols Number of columns.
62     */
63    public AboutDialog(Window owner, int rows, int cols) {
64      this.rows = rows;
65      this.cols = cols;
66      buildWindow(owner);
67    }
68  
69    /**
70     * Main constructor.
71     * 
72     * <p>Builds window and menus.
73     * 
74     * @param owner Owner of Dialog
75     */
76    public AboutDialog(Window owner) {
77      buildWindow(owner);
78    }
79  
80    /**
81     * Construct the window.
82     * 
83     * @param owner parent window
84     */
85    private void buildWindow(Window owner) {
86      aboutWnd = new JDialog(owner, "Info", JDialog.ModalityType.DOCUMENT_MODAL);
87      aboutWnd.addWindowListener(new MyWindowAdapter());
88      // located in middle of quimp qindow
89      Rectangle orgBounds = owner.getBounds();
90      aboutWnd.setBounds(orgBounds.x + orgBounds.width / 2, orgBounds.y + orgBounds.height / 2, 600,
91              400);
92      JPanel p = new JPanel();
93      p.setLayout(new GridLayout(1, 1)); // main window panel
94      JPanel tp = new JPanel(); // panel with text area
95      tp.setLayout(new GridLayout(1, 1));
96      info = new JTextArea(rows, cols); // area to write
97      info.setBackground(Color.WHITE);
98      info.setEditable(false);
99      Font font = new Font(Font.MONOSPACED, Font.PLAIN, 11);
100     info.setFont(font);
101     tp.add(info); // add to panel
102     JScrollPane infoPanel = new JScrollPane(tp);
103     p.add(infoPanel);
104     aboutWnd.add(p);
105     aboutWnd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
106     // build menus
107     buildMenu();
108     aboutWnd.setJMenuBar(mbar);
109     // add actions for mouse click
110     MouseListener popupListener = new PopupListener();
111     aboutWnd.addMouseListener(popupListener);
112     info.addMouseListener(popupListener);
113     aboutWnd.pack();
114   }
115 
116   /**
117    * Create simple menu bar with entries and popup.
118    * 
119    * <p>Fills private fields of this class.
120    */
121   private void buildMenu() {
122     mbar = new JMenuBar();
123     popup = new JPopupMenu();
124     JMenu medit = new JMenu("Edit");
125     JMenuItem selectall = new JMenuItem("Select All"); // name must follow actionPerformed
126     JMenuItem copy = new JMenuItem("Copy"); // changing the name must follow actionPerformed
127     selectall.addActionListener(this);
128     copy.addActionListener(this);
129     mbar.add(medit);
130     popup.add(selectall);
131     popup.add(copy);
132     medit.add(copyMenuItem(selectall)); // add copy of MenuItems to MenuBar
133     medit.add(copyMenuItem(copy));
134 
135     selectall.addActionListener(this);
136     copy.addActionListener(this);
137   }
138 
139   /**
140    * Make copy of MenuItem.
141    * 
142    * <p>Components can not be shared among containers. This method copies basic properties of
143    * component to its new instance (shallow copy of selected properties)
144    * 
145    * @param src source MenuItem
146    * @return Copy of \limiter src MenuItem
147    */
148   private JMenuItem copyMenuItem(JMenuItem src) {
149     JMenuItem dst = new JMenuItem();
150     dst.setText(src.getText());
151     dst.setToolTipText(src.getToolTipText());
152     dst.setMnemonic(src.getMnemonic());
153     for (ActionListener a : src.getActionListeners()) {
154       dst.addActionListener(a);
155     }
156     return dst;
157   }
158 
159   /**
160    * Add line of text to window TextArea.
161    * 
162    * @param t Text to add in subsequent lines.
163    */
164   public void appendLine(final String t) {
165     info.append(t + "\n");
166   }
167 
168   /**
169    * Add line of length of window.
170    */
171   public void appendDistance() {
172     String line;
173     line = new String(new char[cols]).replace("\0", limiter);
174     appendLine(line);
175   }
176 
177   /**
178    * Show or hide main window.
179    * 
180    * <p><b>Warning</b><br>
181    * When window is visible append(final String) does not work.
182    * 
183    * @param state \limiter true to show window
184    */
185   public void setVisible(boolean state) {
186     info.setCaretPosition(0); // causes that initially view is scrolled to up
187     aboutWnd.setVisible(state);
188   }
189 
190   /**
191    * Destroy window on exit.
192    * 
193    * @author p.baniukiewicz
194    *
195    */
196   class MyWindowAdapter extends WindowAdapter {
197 
198     /*
199      * (non-Javadoc)
200      * 
201      * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
202      */
203     @Override
204     public void windowClosing(WindowEvent we) {
205       LOGGER.trace("windowClosing");
206       aboutWnd.dispose();
207     }
208   }
209 
210   /**
211    * Support for popupmenu.
212    * 
213    * @author p.baniukiewicz
214    *
215    */
216   class PopupListener extends MouseAdapter {
217 
218     /*
219      * (non-Javadoc)
220      * 
221      * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
222      */
223     public void mousePressed(MouseEvent e) {
224       maybeShowPopup(e);
225     }
226 
227     /*
228      * (non-Javadoc)
229      * 
230      * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
231      */
232     public void mouseReleased(MouseEvent e) {
233       maybeShowPopup(e);
234     }
235 
236     private void maybeShowPopup(MouseEvent e) {
237       if (e.isPopupTrigger()) {
238         popup.show(e.getComponent(), e.getX(), e.getY());
239       }
240     }
241   }
242 
243   /**
244    * Menu actions support.
245    * 
246    * @param e event - currently method uses names of events (names of menus)
247    */
248   @Override
249   public void actionPerformed(ActionEvent e) {
250     switch (e.getActionCommand()) {
251       case "Copy":
252         info.copy();
253         break;
254       case "Select All":
255         info.selectAll();
256         break;
257       default:
258         break;
259     }
260 
261   }
262 }