如何正确地重新绘制自定义框架?

时间:2017-05-21 16:21:03

标签: java swing user-interface jframe

我正在尝试创建自己的基于swing的自定义GUI工具包作为一个侧面项目。我的问题是这样的:我创建了一个带退出和最小化按钮的框架但是当我使用最小化按钮并再次最大化时,窗口的格式不正确。这是我的框架类代码。

package com.SMS.GUI;

import java.awt.Color;
import java.awt.Frame;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;


/**
 *
 * @author Marc
 */
final class SMSFrame extends JFrame implements MouseListener{

GUIButton minimizeButton, exitButton;
JPanel titleBar;

SMSFrame(int width, int height){
    setResizable(false);
    setUndecorated(true);
    setSize(width,height);
    getContentPane().setBackground(Color.decode("#8e44ad"));
    setVisible(true);

    minimizeButton = new GUIButton((width-100),0,50,50,"#1abc9c");
    exitButton = new GUIButton((width-50), 0, 50, 50, "#d35400");
    titleBar = new JPanel();

    titleBar.setBackground(Color.decode("#2c3e50"));
    titleBar.setBounds(0, 0, width, 50);


    minimizeButton.addMouseListener(this);
    exitButton.addMouseListener(this);


    add(titleBar);
    titleBar.add(exitButton);
    titleBar.add(minimizeButton);

}


@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
    if(e.getSource() == exitButton){
        exitButton.setBackground(Color.decode("#c0392b"));
    }

    if(e.getSource() == minimizeButton){
        minimizeButton.setBackground(Color.decode("#2ecc71"));
    }
}

@Override
public void mouseReleased(MouseEvent e) {
    if(e.getSource() == exitButton){
        System.exit(0);
    }

    if(e.getSource() == minimizeButton){
        super.setState(JFrame.ICONIFIED);
    }
}

@Override
public void mouseEntered(MouseEvent e) {
    if(e.getSource() == exitButton){
        exitButton.setBackground(Color.decode("#e74c3c"));
    }

    if(e.getSource() == minimizeButton){
        minimizeButton.setBackground(Color.decode("#16a085"));
    }
}

@Override
public void mouseExited(MouseEvent e) {
    if(e.getSource() == exitButton){
        exitButton.setBackground(Color.decode("#d35400"));
    }

    if(e.getSource() == minimizeButton){
        minimizeButton.setBackground(Color.decode("#1abc9c"));
    }
}
}

以下是自定义按钮的代码(我使用了JPanels)。     包com.SMS.GUI;

import java.awt.Color;
import javax.swing.JPanel;


final class GUIButton extends JPanel{
        GUIButton(int x, int y, int width, int height, String hexidecimal_colour){
        setBackground(Color.decode(hexidecimal_colour));
        setBounds(x, y, width, height);
    }

        GUIButton(int width, int height, String hexidecimal_colour){
        setBackground(Color.decode(hexidecimal_colour));
        setSize(width, height);
    }
}

这是在最小化之前帧的外观:

enter image description here

这是它的照顾方式: enter image description here

2 个答案:

答案 0 :(得分:3)

  

然而,当我使用最小化按钮并再次最大化时,窗口的格式不正确。

如果要自定义组件,您确实需要了解Swing的工作原理。 Swing旨在与layout managers一起使用。 JFrame的内容窗格的默认布局管理器是BorderLayoutJPanel的默认布局管理器是FlowLayout

setSize()和/或setBounds()方法仅在帧被重新验证"之后才起作用。当框架恢复到大小时,将调用每个组件的布局管理器,并以所需的大小显示所有组件。

titleBar = new JPanel();

所以," titleBar"上的按钮调整大小为其首选大小,因为它们使用默认FlowLayout。然后FlowLayout将按钮放在面板的中央。

要解决此问题,您需要覆盖getPreferredSize()类的GuiButton方法。另外,摆脱所有与位置相关的代码。布局管理器可以设置位置/大小。

由于您希望按钮对齐到面板右侧,因此您需要更改布局管理器以使用right aligned FlowLayout。阅读FlowLayout API以获取在创建布局管理器时使用的正确构造函数。

add(titleBar);

这会添加" titleBar"到CENTER的{​​{1}},所以当重新验证框架时,此面板现在将根据BorderLayout的规则覆盖整个框架。

要解决此问题,您可以使用:

BorderLayout

现在标题栏只显示在框架的顶部。

因此,您需要阅读Layout Managers上的Swing教程以了解这些更改。本教程包含add(titleBar, BorderLayout.PAGE_START); BorderLayout

的工作示例

我还建议您阅读有关简单框架基础知识的How to Make Frames部分,包括更好的代码结构。示例代码显示了语句执行的顺序,因此FlowLayout是最后一个语句。

答案 1 :(得分:0)

您可以在取消对窗口进行取消复制时尝试重新绘制或重新验证。为此,实现WindowListener并使用此方法:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="row">
    asdf
  </div>
  <div class="row" id="responsive-iframe">
    <div class="embed-responsive embed-responsive-16by9" id="iframe-embed">
        <iframe class="embed-responsive-item" src="" id="iframe" ></iframe>
    </div>
  </div>
  <div class="row">
    bar
  </div>
</div>

不要忘记@Override public void windowDeiconified(WindowEvent e) { //back to normal you could use this.setState(JFrame.NORMAL); //do stuff here. }

此外,您还扩展了JFrame,因此您可以调用this.addWindowListener(this);而不是this.setState(JFrame.ICONIFIED);方法。 它不是一个完整的解决方案,但绝对是组件绘画的问题。