2012-07-02 57 views
0
if (Desktop.isDesktopSupported()) 
    { 
     Desktop.getDesktop().browse(URI.create(URL)); 
    } 

我该如何编辑在此处打开的窗口的位置和大小?它将需要有可能做跨平台。如果没有跨平台的解决方案,那么Desktop适用于什么解决方案?修改从Desktop.Browser打开的窗口的位置和位置

(这是远走高飞的问题,但我也放大到网页的一部分?)

(也关的问题,但如果有另一种方式来打开的窗口,与包括手柄,怎么可以这样做吗?)

+1

我知道一个平台相关的解决方案,但只适用于Windows,它需要JNA或JNI。 –

+0

我需要它是跨平台的,但我对你的方法很感兴趣。 –

+0

感谢编辑Dimo。 –

回答

2

从我的经验来看,getDesktop().browse(URI.create(URL));在Mac上无法正常工作,所以即使您可以找到相当于Mac的@Hovercraft Full Eels解决方案,也无所谓。

我还没有在Mac上测试过使用Java 7.1的桌面,但它没有与以前的Java版本兼容。

如果您真的想跨平台,我认为您需要使用JavaFX中的WebView - JavaFX现在可以在Mac上使用,它是一个功能齐全的浏览器。有很多关于将JavaFX与Swing混合的教程,我认为[JavaFX示例]包含了webView。 1

+0

这是否也工作在LWJGL(似乎无法通过谷歌搜索找到答案) –

+1

LWJGL是纯Java的,对不对?如果客户端桌面安装了JavaFX运行时(现在可以自动识别最新的Java 7下载),您可以从Java应用程序启动带有Web视图的JavaFX场景并将其指向您选择的网页。 – Thorn

+0

不知道,我是从C#背景进入游戏“我的世界”修改。我不知道所有关于它的信息,但我会试试这个。谢谢您的帮助。 –

2

这就是我在Windows平台设置中移动和重新调整Windows大小的方式。这是我的一些USER32 JNA的Windows代码库的一小部分:

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 

import javax.swing.*; 

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.win32.StdCallLibrary; 

@SuppressWarnings("serial") 
public class TestMoveWindow extends JPanel { 
    public static final String[] BOUNDS_NAMES = { "x", "y", "w", "h" }; 
    private JTextField windowNameField = new JTextField(15); 
    private JTextField[] boundsFields = new JTextField[BOUNDS_NAMES.length]; 

    public TestMoveWindow() { 
     JPanel winNamePanel = new JPanel(); 
     winNamePanel.add(new JLabel("Window Name:")); 
     winNamePanel.add(windowNameField); 

     JPanel boundsPanel = new JPanel(new GridLayout(1, 0, 5, 0)); 
     for (int i = 0; i < BOUNDS_NAMES.length; i++) { 
     JPanel fieldPanel = new JPanel(); 
     fieldPanel.add(new JLabel(BOUNDS_NAMES[i] + ":")); 
     boundsFields[i] = new JTextField(3); 
     fieldPanel.add(boundsFields[i]); 
     boundsPanel.add(fieldPanel); 
     } 

     JPanel btnPanel = new JPanel(); 

     Action doItAction = new AbstractAction("Do it!") { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      String startOfWindowName = windowNameField.getText().trim(); 
      Pointer hWnd = JnaUtil.getWinHwnd(startOfWindowName); 
      if (hWnd == null || startOfWindowName.isEmpty()) { 
       String message = String.format(
        "Window named \"%s\" was not found", startOfWindowName); 
       JOptionPane.showMessageDialog(TestMoveWindow.this, message, 
        "Window Not Found", JOptionPane.ERROR_MESSAGE); 
       return; 
      } 
      int x = 0; 
      int y = 0; 
      int w = 0; 
      int h = 0; 

      String xStr = boundsFields[0].getText(); 
      String yStr = boundsFields[1].getText(); 
      String wStr = boundsFields[2].getText(); 
      String hStr = boundsFields[3].getText(); 
      try { 
       x = Integer.parseInt(xStr); 
       y = Integer.parseInt(yStr); 
       w = Integer.parseInt(wStr); 
       h = Integer.parseInt(hStr); 
      } catch (NumberFormatException e1) { 
       String message = String 
        .format(
          "Numbers cannot be parsed: \"%s\", \"%s\", \"%s\", \"%s\"", 
          xStr, yStr, wStr, hStr); 
       JOptionPane.showMessageDialog(TestMoveWindow.this, message, 
        "Numbers Not Parseable", JOptionPane.ERROR_MESSAGE); 
       return; 
      } 

      JnaUtil.moveWindow(hWnd, x, y, w, h); 

     } 
     }; 
     btnPanel.add(new JButton(doItAction)); 

     windowNameField.addActionListener(doItAction); 
     for (JTextField boundField : boundsFields) { 
     boundField.addActionListener(doItAction); 
     } 

     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 
     add(winNamePanel); 
     add(boundsPanel); 
     add(btnPanel); 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Test Move Window"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new TestMoveWindow()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 

} 

class JnaUtil { 
    private static final User32 user32 = User32.INSTANCE; 
    private static Pointer callBackHwnd; 

    public static Pointer getWinHwnd(final String startOfWindowName) { 
     callBackHwnd = null; 

     user32.EnumWindows(new User32.WNDENUMPROC() { 
     @Override 
     public boolean callback(Pointer hWnd, Pointer userData) { 
      byte[] windowText = new byte[512]; 
      user32.GetWindowTextA(hWnd, windowText, 512); 
      String wText = Native.toString(windowText).trim(); 

      if (!wText.isEmpty() && wText.startsWith(startOfWindowName)) { 
       callBackHwnd = hWnd; 
       return false; 
      } 
      return true; 
     } 
     }, null); 
     return callBackHwnd; 
    } 

    public static boolean moveWindow(Pointer hWnd, int x, int y, int nWidth, 
     int nHeight) { 
     boolean bRepaint = true; 
     return user32.MoveWindow(hWnd, x, y, nWidth, nHeight, bRepaint); 
    } 

} 

interface User32 extends StdCallLibrary { 
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class); 

    interface WNDENUMPROC extends StdCallCallback { 
     boolean callback(Pointer hWnd, Pointer arg); 
    } 

    boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer userData); 

    boolean MoveWindow(Pointer hWnd, int x, int y, int nWidth, int nHeight, 
     boolean bRepaint); 

    int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount); 

} 

这就要求你必须从你的classpath的JNA库jna.jar和platform.jar。而且,这仅适用于Windows平台。代码的第一部分,TestMoveWindow只是一个用于演示程序如何工作的测试GUI,它实际上只不过是对JnaUtil.moveWindow(hWnd, x, y, w, h);的调用,但代码的“肉”是我的JnaUtil类和User32接口。 JNA图书馆做这个所以容易,这是荒谬的。为了让我的代码正常工作,您还需要知道窗口文本的开始 - 通常是网页的标题 - 以便它可以获得指向窗口的指针。

我真的不知道是否存在任何跨平台的解决方案。我想认为有,但我有点怀疑,因为我相信这总是需要系统调用,但我很想证明是错误的!

+0

即使没有简单的跨平台解决方案存在,每个主要操作系统(Linux,Mac,Windows)的解决方案应该存在,是否正确? –

+1

@Gavin:绝对是!但不要试图问我*任何有关Unix,Mac或Windows以外的任何东西。 :) –