2016-09-18 81 views
0

所以在我的窗口中,我將JFrame設置爲undecorated(true),並在頂部具有我自己的自定義標題(通過關閉和最小化按鈕)。我遇到的唯一問題是當您拖動此「自定義標題」時,窗口會移動。整個標題爲JPanel,然後將其添加到北側的JFrameBorderLayout.NORTH)。我有一個MouseListenerMouseMotionListener添加到此JPanel,但它不承認任何事件。我可以假設的唯一的事情就是我如何設計佈局。下面是標題的代碼,並附帶一個可視化的代碼。JPanel失去焦點並且聽衆沒有射擊

CODE:

private void addHeader() 
{ 
    headPane = new JPanel(); 
    headPane.setLayout(new BoxLayout(headPane, BoxLayout.LINE_AXIS)); 
    buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2)); 
    buttonPane.setBackground(mouseLineColor); 
    headPane.setBackground(Color.GREEN); 

    Font buttonFont = new Font("", Font.PLAIN, 18); 
    minimize.setFocusable(false); 
    minimize.setPreferredSize(new Dimension(30, 20)); 
    minimize.setMargin(new Insets(0, 0, 0, 0)); 
    minimize.setOpaque(false); 
    minimize.setBorder(null); 
    minimize.setForeground(Color.WHITE); 
    minimize.setOpaque(true); 
    minimize.setFont(buttonFont); 
    minimize.setBackground(buttonColor); 

    quit.setFocusable(false); 
    quit.setPreferredSize(new Dimension(30, 20)); 
    quit.setMargin(new Insets(0, 0, 0, 0)); 
    quit.setOpaque(false); 
    quit.setBorder(null); 
    quit.setForeground(Color.WHITE); 
    quit.setOpaque(true); 
    quit.setFont(buttonFont); 
    quit.setBackground(buttonColor); 

    back.setFocusable(false); 
    back.setPreferredSize(new Dimension(30, 20)); 
    back.setMargin(new Insets(0, 0, 0, 0)); 
    back.setOpaque(false); 
    back.setBorder(null); 
    back.setForeground(Color.WHITE); 
    back.setOpaque(true); 
    back.setFont(buttonFont); 
    back.setBackground(buttonColor); 

    if(screen != GAME_MENU) 
     buttonPane.add(back); 
    else 
     buttonPane.remove(back); 

    buttonPane.add(minimize); 
    buttonPane.add(quit); 

    headTitle = new JLabel("Bouncy Ball Version " + VERSION); 
    headTitle.setBorder(new EmptyBorder(0, 5, 0, 0)); 
    headTitle.setFont(new Font("", Font.BOLD, 14)); 
    headTitle.setForeground(Color.BLACK); 
    headTitle.setBackground(Color.YELLOW); 
    headTitle.setOpaque(true); 
    headTitle.setFocusable(false); 
    headPane.setFocusable(false); 
    buttonPane.setFocusable(false); 

    buttonPane.setBackground(Color.RED); 

    headPane.add(headTitle); 
    headPane.add(Box.createHorizontalGlue()); 
    headPane.add(buttonPane); 

    if(callOnce) 
    { 
     minimize.addActionListener(this); 
     quit.addActionListener(this); 
     back.addActionListener(this); 

     minimize.addMouseListener(this); 
     quit.addMouseListener(this); 
     back.addMouseListener(this); 

     headPane.addMouseListener(this); 
     headPane.addMouseMotionListener(this); 

     callOnce = false; 
    } 

    headPane.setPreferredSize(new Dimension(headPane.getPreferredSize().width, 24)); 
    frame.add(headPane, BorderLayout.NORTH); 
} 

聽衆:

的mousePressed:

Object source = e.getSource(); 
if(source == headPane) 
{ 
    mouseX = e.getX(); 
    mouseY = e.getY(); 
    movingWindow = true; 
} 

的mouseDragged:

Object source = e.getSource(); 
if(source == headPane) 
{ 
    if(movingWindow) 
    { 
     int x = e.getXOnScreen(); 
     int y = e.getYOnScreen(); 
     frame.setLocation(x - mouseX, y - mouseY); 
    } 
} 

enter image description here

我還要補充一點,當我點擊headPane,該JButton旨意停止正常工作。我不知道爲什麼這樣做,或者如果答案非常簡單,我只是很笨,但我沒有試過的東西已經奏效。

我對Java相當陌生,所以在此先感謝您的幫助。

+2

1)爲了更快地獲得更好的幫助,請發佈[MCVE]或[簡短自包含正確示例](http://www.sscce.org/)(而不僅僅是不可編譯的代碼片段)。 2)*「..預先感謝任何幫助。」*如果你問了一個問題,它會有所幫助! –

回答

2

我看不需要「callOnce」變量。框架和添加到框架的組件只能在創建類時創建一次。如果你不止一次調用「addHeader()」方法,那麼我建議你有一個設計問題。

此外,您不應該將ActionListeners添加到您的按鈕兩次。

我遇到的唯一問題是當您拖動此「自定義標題」時,窗口會移動。

檢出Moving Windows爲通用類,允許您拖動任何組件。通常情況下,您需要在面板中拖動組件。

但是,該類還具有一項功能,可讓您通過拖動添加到窗口的組件拖動桌面上的窗口。

+0

移動Windows類非常有用,並且爲我所需要的完美工作,所以非常感謝。我確實有一個問題,但有關添加標題本身。我不止一次調用「addHeader()」方法,主要是因爲我已經有了後退按鈕。無論何時移動到不同的屏幕,我都會回想起「addHeader()」方法來確定後退按鈕是否應該在那裏。有沒有更好的方法來做到這一點? – Ryan

+0

哦,還有一件事你可能會或可能無法回答,有沒有辦法讓移動Windows類在多個顯示器上工作? – Ryan

+1

@Ryan,不需要重新創建整個面板。您可以根據需要啓用/禁用後退按鈕。或者你可以讓後退按鈕可見/不可見。我從來沒有玩過多臺顯示器,所以我不知道需要什麼來讓ComponentMover與多臺顯示器一起工作。 – camickr