OSDN Git Service

Mavenプラグイン更新
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / dxchg / WebIPCDialog.java
1 /*
2  * Dialog for WebIPC
3  *
4  * License : The MIT License
5  * Copyright(c) 2009 olyutorskii
6  */
7
8 package jp.sfjp.jindolf.dxchg;
9
10 import java.awt.Container;
11 import java.awt.Frame;
12 import java.awt.GridBagConstraints;
13 import java.awt.GridBagLayout;
14 import java.awt.Insets;
15 import java.awt.datatransfer.Transferable;
16 import java.awt.event.ActionEvent;
17 import java.awt.event.ActionListener;
18 import java.awt.event.MouseAdapter;
19 import java.awt.event.MouseEvent;
20 import java.awt.event.WindowAdapter;
21 import java.awt.event.WindowEvent;
22 import java.io.IOException;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.util.logging.Logger;
26 import javax.swing.BorderFactory;
27 import javax.swing.Icon;
28 import javax.swing.JButton;
29 import javax.swing.JComponent;
30 import javax.swing.JDialog;
31 import javax.swing.JLabel;
32 import javax.swing.JOptionPane;
33 import javax.swing.JPanel;
34 import javax.swing.JTextArea;
35 import javax.swing.SwingConstants;
36 import javax.swing.TransferHandler;
37 import javax.swing.border.Border;
38 import javax.swing.border.EtchedBorder;
39 import jp.sfjp.jindolf.JreChecker;
40 import jp.sfjp.jindolf.VerInfo;
41 import jp.sfjp.jindolf.util.GUIUtils;
42 import jp.sfjp.jindolf.util.Monodizer;
43
44 /**
45  * Webブラウザ起動用の専用ダイアログ。
46  */
47 @SuppressWarnings("serial")
48 public class WebIPCDialog
49         extends JDialog
50         implements ActionListener {
51
52     private static final String TITLE_WWW =
53             VerInfo.getFrameTitle("URLへのアクセス確認");
54
55
56     private static final Logger LOGGER = Logger.getAnonymousLogger();
57
58
59     private final String warnMessage;
60
61     private final JLabel info =
62             new JLabel("以下のURLへのアクセスが指示されました。");
63     private final JTextArea urltext =
64             new JTextArea("");
65     private final JButton browse =
66             new JButton("デフォルトのWebブラウザで表示");
67     private final JButton clipcopy =
68             new JButton("URLをクリップボードにコピー");
69     private final JLabel dndLabel =
70             new JLabel("…またはブラウザにDrag&Drop →");
71     private final JButton cancel =
72             new JButton("閉じる");
73
74     private final WebIPC ipc;
75
76     private URI uri;
77
78
79     /**
80      * コンストラクタ。
81      * @param owner オーナーフレーム
82      */
83     public WebIPCDialog(Frame owner){
84         super(owner);
85         setModal(true);
86
87         GUIUtils.modifyWindowAttributes(this, true, false, true);
88
89         WebIPC webipc = null;
90         if(WebIPC.isDesktopSupported()){
91             webipc = WebIPC.getWebIPC();
92             if( ! webipc.isSupported(WebIPC.Action.BROWSE) ){
93                 webipc = null;
94             }
95         }
96         this.ipc = webipc;
97
98         if(this.ipc == null){
99             if( ! JreChecker.has16Runtime() ){
100                 this.warnMessage =
101                         "この機能を利用するには、JRE1.6以上が必要です";
102             }else{
103                 this.warnMessage =
104                         "何らかの理由でこの機能は利用不可になっています";
105             }
106         }else{
107             this.warnMessage = "";
108         }
109
110         Border inside =
111                 BorderFactory.createEmptyBorder(1, 4, 1, 4);
112         Border outside =
113                 BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
114         Border border =
115                 BorderFactory.createCompoundBorder(outside, inside);
116         this.urltext.setBorder(border);
117         this.urltext.setEditable(false);
118         this.urltext.setLineWrap(true);
119         this.urltext.setComponentPopupMenu(new TextPopup());
120         Monodizer.monodize(this.urltext);
121
122         this.dndLabel.setIcon(GUIUtils.getWWWIcon());
123         this.dndLabel.setHorizontalTextPosition(SwingConstants.LEFT);
124         this.dndLabel.setTransferHandler(new DnDHandler());
125         this.dndLabel.addMouseListener(new DragIgniter());
126
127         Container container = getContentPane();
128         design(container);
129
130         this.browse  .addActionListener(this);
131         this.clipcopy.addActionListener(this);
132         this.cancel  .addActionListener(this);
133
134         getRootPane().setDefaultButton(this.browse);
135         this.browse.requestFocusInWindow();
136
137         if(this.ipc == null){
138             this.browse.setToolTipText(this.warnMessage);
139         }
140
141         setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
142         addWindowListener(new WindowAdapter(){
143             @Override
144             public void windowClosing(WindowEvent event){
145                 actionCancel();
146                 return;
147             }
148         });
149
150         return;
151     }
152
153     /**
154      * Webブラウザ起動用のモーダルダイアログを表示する。
155      * @param owner オーナーフレーム
156      * @param url URL文字列
157      */
158     public static void showDialog(Frame owner, String url){
159         WebIPCDialog dialog = new WebIPCDialog(owner);
160
161         dialog.setTitle(TITLE_WWW);
162         dialog.setUrlText(url);
163         dialog.pack();
164         dialog.setLocationRelativeTo(owner);
165         dialog.setVisible(true);
166
167         return;
168     }
169
170     /**
171      * 有効なURIか判定する。
172      * @param uri URI
173      * @return 有効ならtrue
174      */
175     private static boolean isValidURI(URI uri){
176         if(uri == null) return false;
177
178         if( ! uri.isAbsolute() ) return false;
179
180         String scheme = uri.getScheme();
181         if(scheme == null) return false;
182         if(   ! scheme.equalsIgnoreCase("http")
183            && ! scheme.equalsIgnoreCase("https") ) return false;
184
185         String host = uri.getHost();
186         if(host == null) return false;
187
188         return true;
189     }
190
191     /**
192      * レイアウトを行う。
193      * @param container レイアウトコンテナ
194      */
195     private void design(Container container){
196         GridBagLayout layout = new GridBagLayout();
197         GridBagConstraints constraints = new GridBagConstraints();
198         container.setLayout(layout);
199
200         JComponent buttonPanel = buildButtonPanel();
201
202         constraints.gridwidth = GridBagConstraints.REMAINDER;
203         constraints.fill      = GridBagConstraints.HORIZONTAL;
204         constraints.insets    = new Insets(5, 5, 5, 5);
205
206         container.add(this.info,   constraints);
207         container.add(this.urltext, constraints);
208         container.add(buttonPanel,    constraints);
209         container.add(this.cancel,   constraints);
210
211         return;
212     }
213
214     /**
215      * ボタンパネルを生成する。
216      * @return ボタンパネル
217      */
218     private JComponent buildButtonPanel(){
219         JPanel buttonPanel = new JPanel();
220
221         Border border = BorderFactory.createTitledBorder(
222                             "アクセスする方法を選択してください。"
223                         );
224         buttonPanel.setBorder(border);
225
226         GridBagLayout layout = new GridBagLayout();
227         GridBagConstraints constraints = new GridBagConstraints();
228         buttonPanel.setLayout(layout);
229
230         constraints.gridwidth = GridBagConstraints.REMAINDER;
231         constraints.fill      = GridBagConstraints.HORIZONTAL;
232         constraints.insets    = new Insets(3, 3, 3, 3);
233         buttonPanel.add(this.browse,   constraints);
234         buttonPanel.add(this.clipcopy, constraints);
235
236         constraints.fill   = GridBagConstraints.NONE;
237         constraints.anchor = GridBagConstraints.EAST;
238         constraints.insets    = new Insets(10, 3, 10, 3);
239         buttonPanel.add(this.dndLabel, constraints);
240
241         return buttonPanel;
242     }
243
244     /**
245      * URL文字列を設定する。
246      * @param url URL文字列
247      */
248     public void setUrlText(String url){
249         URI uriarg = null;
250         try{
251             uriarg = new URI(url);
252         }catch(URISyntaxException e){
253             // NOTHING
254         }
255
256         this.uri = uriarg;
257         if(this.uri == null) return;
258
259         if( ! isValidURI(this.uri) ) return;
260
261         String uriText = this.uri.toASCIIString();
262         this.urltext.setText(uriText);
263
264         this.urltext.revalidate();
265         pack();
266
267         return;
268     }
269
270     /**
271      * ボタン押下リスナ。
272      * @param event ボタン押下イベント
273      */
274     @Override
275     public void actionPerformed(ActionEvent event){
276         Object source = event.getSource();
277         if(source == this.browse){
278             actionBrowse();
279         }else if(source == this.clipcopy){
280             actionClipboardCopy();
281         }else if(source == this.cancel){
282             actionCancel();
283         }
284         return;
285     }
286
287     /**
288      * WebブラウザでURLを表示。
289      */
290     private void actionBrowse(){
291         if(this.uri == null){
292             close();
293             return;
294         }
295
296         if(this.ipc == null){
297             String title;
298             if( ! JreChecker.has16Runtime() ){
299                 title = "新しいJavaを入手しましょう";
300             }else{
301                 title = "報告";
302             }
303             JOptionPane.showMessageDialog(
304                     this,
305                     this.warnMessage, title,
306                     JOptionPane.INFORMATION_MESSAGE);
307             return;
308         }
309
310         try{
311             try{
312                 this.ipc.browse(this.uri);
313             }catch(NullPointerException e){
314                 assert false;
315             }catch(UnsupportedOperationException e){
316                 // NOTHING
317             }catch(IOException e){
318                 // NOTHING
319             }catch(SecurityException e){
320                 // NOTHING
321             }catch(IllegalArgumentException e){
322                 // NOTHING
323             }
324             String logmsg =   "URL "
325                             + this.uri.toASCIIString()
326                             + " へのアクセスをWebブラウザに指示しました";
327             LOGGER.info(logmsg);
328         }finally{
329             close();
330         }
331
332         return;
333     }
334
335     /**
336      * URLをクリップボードにコピーする。
337      */
338     private void actionClipboardCopy(){
339         if(this.uri == null){
340             close();
341             return;
342         }
343
344         String uristring = this.uri.toASCIIString();
345
346         try{
347             ClipboardAction.copyToClipboard(uristring);
348             String logmsg =  "文字列「"
349                            + uristring
350                            + "」をクリップボードにコピーしました";
351             LOGGER.info(logmsg);
352         }finally{
353             close();
354         }
355
356         return;
357     }
358
359     /**
360      * 何もせずダイアログを閉じる。
361      */
362     private void actionCancel(){
363         close();
364         return;
365     }
366
367     /**
368      * ダイアログを閉じる。
369      */
370     private void close(){
371         setVisible(false);
372         return;
373     }
374
375     /**
376      * Drag&Dropの転送処理を管理。
377      */
378     private class DnDHandler extends TransferHandler{
379
380         /**
381          * コンストラクタ。
382          */
383         public DnDHandler(){
384             super();
385             return;
386         }
387
388         /**
389          * {@inheritDoc}
390          * コピー動作のみをサポートすることを伝える。
391          * @param comp {@inheritDoc}
392          * @return {@inheritDoc}
393          */
394         @Override
395         public int getSourceActions(JComponent comp){
396             return 0 | COPY;
397         }
398
399         /**
400          * {@inheritDoc}
401          * URIエクスポータを生成する。
402          * URIも指定される。
403          * @param comp {@inheritDoc}
404          * @return {@inheritDoc}
405          */
406         @Override
407         protected Transferable createTransferable(JComponent comp){
408             UriExporter result = new UriExporter(WebIPCDialog.this.uri);
409             return result;
410         }
411
412         /**
413          * {@inheritDoc}
414          * D&Dに成功したらダイアログを閉じる。
415          * @param source {@inheritDoc}
416          * @param data {@inheritDoc}
417          * @param action {@inheritDoc}
418          */
419         @Override
420         protected void exportDone(JComponent source,
421                                    Transferable data,
422                                    int action ){
423             if(action == NONE) return;
424
425             String logmsg =   "URL "
426                             + WebIPCDialog.this.uri.toASCIIString()
427                             + " がどこかへドラッグ&ドロップされました";
428             LOGGER.info(logmsg);
429
430             close();
431
432             return;
433         }
434
435         /**
436          * {@inheritDoc}
437          * ※ SunのJRE1.6.0_11前後では、BugID 4816922のため決して呼ばれない。
438          * @param tx {@inheritDoc}
439          * @return {@inheritDoc}
440          */
441         @Override
442         public Icon getVisualRepresentation(Transferable tx){
443             return GUIUtils.getWWWIcon();
444         }
445
446     }
447
448     /**
449      * ドラッグ開始イベント処理。
450      */
451     private static class DragIgniter extends MouseAdapter{
452
453         /**
454          * コンストラクタ。
455          */
456         public DragIgniter(){
457             super();
458             return;
459         }
460
461         /**
462          * {@inheritDoc}
463          * ドラッグ開始イベント受信。
464          * @param event {@inheritDoc}
465          */
466         @Override
467         public void mousePressed(MouseEvent event){
468             JComponent comp = (JComponent)event.getSource();
469             TransferHandler handler = comp.getTransferHandler();
470             handler.exportAsDrag(comp, event, TransferHandler.COPY);
471             return;
472         }
473
474     }
475
476 }