4 * License : The MIT License
5 * Copyright(c) 2009 olyutorskii
8 package jp.sfjp.jindolf.dxchg;
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;
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;
47 @SuppressWarnings("serial")
48 public class WebIPCDialog
50 implements ActionListener {
52 private static final String TITLE_WWW =
53 VerInfo.getFrameTitle("URLへのアクセス確認");
56 private static final Logger LOGGER = Logger.getAnonymousLogger();
59 private final String warnMessage;
61 private final JLabel info =
62 new JLabel("以下のURLへのアクセスが指示されました。");
63 private final JTextArea urltext =
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 =
74 private final WebIPC ipc;
81 * @param owner オーナーフレーム
83 public WebIPCDialog(Frame owner){
87 GUIUtils.modifyWindowAttributes(this, true, false, true);
90 if(WebIPC.isDesktopSupported()){
91 webipc = WebIPC.getWebIPC();
92 if( ! webipc.isSupported(WebIPC.Action.BROWSE) ){
99 if( ! JreChecker.has16Runtime() ){
101 "この機能を利用するには、JRE1.6以上が必要です";
104 "何らかの理由でこの機能は利用不可になっています";
107 this.warnMessage = "";
111 BorderFactory.createEmptyBorder(1, 4, 1, 4);
113 BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
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);
122 this.dndLabel.setIcon(GUIUtils.getWWWIcon());
123 this.dndLabel.setHorizontalTextPosition(SwingConstants.LEFT);
124 this.dndLabel.setTransferHandler(new DnDHandler());
125 this.dndLabel.addMouseListener(new DragIgniter());
127 Container container = getContentPane();
130 this.browse .addActionListener(this);
131 this.clipcopy.addActionListener(this);
132 this.cancel .addActionListener(this);
134 getRootPane().setDefaultButton(this.browse);
135 this.browse.requestFocusInWindow();
137 if(this.ipc == null){
138 this.browse.setToolTipText(this.warnMessage);
141 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
142 addWindowListener(new WindowAdapter(){
144 public void windowClosing(WindowEvent event){
154 * Webブラウザ起動用のモーダルダイアログを表示する。
155 * @param owner オーナーフレーム
158 public static void showDialog(Frame owner, String url){
159 WebIPCDialog dialog = new WebIPCDialog(owner);
161 dialog.setTitle(TITLE_WWW);
162 dialog.setUrlText(url);
164 dialog.setLocationRelativeTo(owner);
165 dialog.setVisible(true);
175 private static boolean isValidURI(URI uri){
176 if(uri == null) return false;
178 if( ! uri.isAbsolute() ) return false;
180 String scheme = uri.getScheme();
181 if(scheme == null) return false;
182 if( ! scheme.equalsIgnoreCase("http")
183 && ! scheme.equalsIgnoreCase("https") ) return false;
185 String host = uri.getHost();
186 if(host == null) return false;
193 * @param container レイアウトコンテナ
195 private void design(Container container){
196 GridBagLayout layout = new GridBagLayout();
197 GridBagConstraints constraints = new GridBagConstraints();
198 container.setLayout(layout);
200 JComponent buttonPanel = buildButtonPanel();
202 constraints.gridwidth = GridBagConstraints.REMAINDER;
203 constraints.fill = GridBagConstraints.HORIZONTAL;
204 constraints.insets = new Insets(5, 5, 5, 5);
206 container.add(this.info, constraints);
207 container.add(this.urltext, constraints);
208 container.add(buttonPanel, constraints);
209 container.add(this.cancel, constraints);
218 private JComponent buildButtonPanel(){
219 JPanel buttonPanel = new JPanel();
221 Border border = BorderFactory.createTitledBorder(
224 buttonPanel.setBorder(border);
226 GridBagLayout layout = new GridBagLayout();
227 GridBagConstraints constraints = new GridBagConstraints();
228 buttonPanel.setLayout(layout);
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);
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);
248 public void setUrlText(String url){
251 uriarg = new URI(url);
252 }catch(URISyntaxException e){
257 if(this.uri == null) return;
259 if( ! isValidURI(this.uri) ) return;
261 String uriText = this.uri.toASCIIString();
262 this.urltext.setText(uriText);
264 this.urltext.revalidate();
272 * @param event ボタン押下イベント
275 public void actionPerformed(ActionEvent event){
276 Object source = event.getSource();
277 if(source == this.browse){
279 }else if(source == this.clipcopy){
280 actionClipboardCopy();
281 }else if(source == this.cancel){
290 private void actionBrowse(){
291 if(this.uri == null){
296 if(this.ipc == null){
298 if( ! JreChecker.has16Runtime() ){
299 title = "新しいJavaを入手しましょう";
303 JOptionPane.showMessageDialog(
305 this.warnMessage, title,
306 JOptionPane.INFORMATION_MESSAGE);
312 this.ipc.browse(this.uri);
313 }catch(NullPointerException e){
315 }catch(UnsupportedOperationException e){
317 }catch(IOException e){
319 }catch(SecurityException e){
321 }catch(IllegalArgumentException e){
324 String logmsg = "URL "
325 + this.uri.toASCIIString()
326 + " へのアクセスをWebブラウザに指示しました";
338 private void actionClipboardCopy(){
339 if(this.uri == null){
344 String uristring = this.uri.toASCIIString();
347 ClipboardAction.copyToClipboard(uristring);
348 String logmsg = "文字列「"
350 + "」をクリップボードにコピーしました";
362 private void actionCancel(){
370 private void close(){
376 * Drag&Dropの転送処理を管理。
378 private class DnDHandler extends TransferHandler{
390 * コピー動作のみをサポートすることを伝える。
391 * @param comp {@inheritDoc}
392 * @return {@inheritDoc}
395 public int getSourceActions(JComponent comp){
403 * @param comp {@inheritDoc}
404 * @return {@inheritDoc}
407 protected Transferable createTransferable(JComponent comp){
408 UriExporter result = new UriExporter(WebIPCDialog.this.uri);
414 * D&Dに成功したらダイアログを閉じる。
415 * @param source {@inheritDoc}
416 * @param data {@inheritDoc}
417 * @param action {@inheritDoc}
420 protected void exportDone(JComponent source,
423 if(action == NONE) return;
425 String logmsg = "URL "
426 + WebIPCDialog.this.uri.toASCIIString()
427 + " がどこかへドラッグ&ドロップされました";
437 * ※ SunのJRE1.6.0_11前後では、BugID 4816922のため決して呼ばれない。
438 * @param tx {@inheritDoc}
439 * @return {@inheritDoc}
442 public Icon getVisualRepresentation(Transferable tx){
443 return GUIUtils.getWWWIcon();
451 private static class DragIgniter extends MouseAdapter{
456 public DragIgniter(){
464 * @param event {@inheritDoc}
467 public void mousePressed(MouseEvent event){
468 JComponent comp = (JComponent)event.getSource();
469 TransferHandler handler = comp.getTransferHandler();
470 handler.exportAsDrag(comp, event, TransferHandler.COPY);