Java Swing:像Linux中的框架一样调整JFrame的大小
我想知道是否有可能以这种方式实现JFrame的大小调整,它的大小调整类似于linux中的standart windows。更准确地说:如果用户开始进行拖动,则只有在预览窗口时才显示未来的大小,而不会调整原始内容的大小。一旦用户释放鼠标,框架就会调整到该大小。在图像中: (1)调整大小前的状态 (2)用户开始拖动(在红色圆圈处) (3)用户释放鼠标,帧的大小将调整 在JavaSwing中有可能实现这一点吗 编辑: 由于该程序有一天也会在较低的JavaRE中运行,因此我尝试将mKorbel建议与半透明框架结合起来,并将注释中的建议与半透明框架结合起来。结果接近目标,只是Java Swing:像Linux中的框架一样调整JFrame的大小,java,swing,jframe,mouse-listeners,componentlistener,Java,Swing,Jframe,Mouse Listeners,Componentlistener,我想知道是否有可能以这种方式实现JFrame的大小调整,它的大小调整类似于linux中的standart windows。更准确地说:如果用户开始进行拖动,则只有在预览窗口时才显示未来的大小,而不会调整原始内容的大小。一旦用户释放鼠标,框架就会调整到该大小。在图像中: (1)调整大小前的状态 (2)用户开始拖动(在红色圆圈处) (3)用户释放鼠标,帧的大小将调整 在JavaSwing中有可能实现这一点吗 编辑: 由于该程序有一天也会在较低的JavaRE中运行,因此我尝试将mKorbel建议
- contentPane的内容在我停止移动鼠标后调整大小,而不是释放鼠标时
- 框架标题会立即调整大小,而不仅仅是在我停止拖动框架边框时
- 仅当从右侧或底部调整大小时,它才起作用,否则内容会随着拖动而移动
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class GroundFrame extends JFrame {
Timer timer;
JPanel panel2;
public GroundFrame() {
super("GradientTranslucentWindow");
setBackground(new Color(0,0,0,0));
setSize(new Dimension(300,200));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel() {
panel.setBackground(new Color(0,0,0,0));
setContentPane(panel);
setLayout(null);
panel2 = new JPanel();
panel2.setBackground(Color.black);
panel2.setBounds(0,0,getContentPane().getWidth(), getContentPane().getHeight());
getContentPane().add(panel2);
addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {}
@Override
public void componentResized(ComponentEvent e) {
timer = new Timer(50, new Action() {
@Override
public void actionPerformed(ActionEvent e) {
if(timer.isRunning()){
}else{
resizePanel(getContentPane().getSize());
}
}
@Override
public void setEnabled(boolean b) {}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {}
@Override
public void putValue(String key, Object value) {}
@Override
public boolean isEnabled() {return false;}
@Override
public Object getValue(String key) {return null;}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {}
});
timer.setRepeats(false);
timer.start();
}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentHidden(ComponentEvent e) {}
});
}
public void resizePanel(Dimension dim){
panel2.setBounds(0,0,dim.width, dim.height);
repaint();
}
public static void main(String[] args) {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported =
gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!isPerPixelTranslucencySupported) {
System.out.println(
"Per-pixel translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GroundFrame gtw = new GroundFrame();
gtw.setVisible(true);
}
});
}
}
如果将预览窗口,则仅显示将来的大小,而
未调整原始内容的大小。一旦用户发布
鼠标移动时,框架大小将调整为该大小
非常复杂的想法,但是
- 将
添加到ComponentListener
JFrame
- 凌驾
- 在那里添加短延迟(400-600),输出到
- 如果继续调整大小,则调用
Timer\restart()
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
public class ComponentEventDemo extends JPanel
implements ComponentListener, HierarchyListener,
ItemListener {
private JFrame frame;
private static final long serialVersionUID = 1L;
private JTextArea display;
private JLabel label;
private JComboBox comboBox;
private JComboBox comboBox1;
private String newline = "\n";
private Vector<String> listSomeString = new Vector<String>();
private Vector<String> listSomeAnotherString = new Vector<String>();
public ComponentEventDemo() {
listSomeString.add("-");
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
listSomeString.add("Pool");
listSomeString.add("None of the above");
//
listSomeAnotherString.add("-");
listSomeAnotherString.add("XxxZxx Snowboarding");
listSomeAnotherString.add("AaaBbb Rowing");
listSomeAnotherString.add("CccDdd Knitting");
listSomeAnotherString.add("Eee Fff Speed reading");
listSomeAnotherString.add("Eee Fff Pool");
listSomeAnotherString.add("Eee Fff None of the above");
comboBox = new JComboBox(listSomeString);
comboBox1 = new JComboBox(listSomeAnotherString);
display = new JTextArea();
display.setEditable(false);
JScrollPane scrollPane = new JScrollPane(display);
scrollPane.setPreferredSize(new Dimension(350, 200));
label = new JLabel("This is a label", JLabel.CENTER);
label.addComponentListener(this);
JCheckBox checkbox = new JCheckBox("Label visible", true);
checkbox.addItemListener(this);
checkbox.addComponentListener(this);
JPanel panel = new JPanel(new GridLayout(1, 2));
panel.add(label);
panel.add(checkbox);
panel.addComponentListener(this);
frame = new JFrame("ComponentEventDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(panel, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
label.setVisible(true);
label.revalidate();
label.repaint();
} else {
label.setVisible(false);
}
}
protected void displayMessage(String message) {
//If the text area is not yet realized, and
//we tell it to draw text, it could cause
//a text/AWT tree deadlock. Our solution is
//to ensure that the text area is realized
//before attempting to draw text.
// if (display.isShowing()) {
display.append(message + newline);
display.setCaretPosition(display.getDocument().getLength());
//}
}
public void componentHidden(ComponentEvent e) {
displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
}
public void componentMoved(ComponentEvent e) {
displayMessage(e.getComponent().getClass().getName() + " --- Moved");
}
public void componentResized(ComponentEvent e) {
displayMessage(e.getComponent().getClass().getName() + " --- Resized ");
}
public void componentShown(ComponentEvent e) {
displayMessage(e.getComponent().getClass().getName() + " --- Shown");
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
ComponentEventDemo componentEventDemo = new ComponentEventDemo();
}
});
}
public void hierarchyChanged(HierarchyEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.*;
导入java.util.Vector;
公共类ComponentEventDemo扩展了JPanel
实现ComponentListener、HierarchyListener、,
项目侦听器{
私有JFrame;
私有静态最终长serialVersionUID=1L;
私人区域显示器;
私人标签;
专用JComboBox组合框;
专用JComboxCombox1;
私有字符串换行符=“\n”;
私有向量listSomeString=新向量();
私有向量listSomeAnotherString=新向量();
公共组件eventdemo(){
添加(“-”);
添加(“滑雪板”);
添加(“划船”);
添加(“编织”);
添加(“快速读取”);
添加(“池”);
添加(“上述任何一项”);
//
listSomeAnotherString.add(“-”);
添加(“XxxZxx滑雪板”);
添加(“aaabb划船”);
listSomeAnotherString.add(“CccDdd”);
添加(“Eee Fff速度读取”);
添加(“EEFFF池”);
listSomeAnotherString.add(“Eee Fff无上述内容”);
comboBox=newjcombobox(listSomeString);
comboBox1=新的JComboBox(listSomeAnotherString);
显示=新的JTextArea();
display.setEditable(false);
JScrollPane scrollPane=新的JScrollPane(显示);
scrollPane.setPreferredSize(新维度(350200));
label=新的JLabel(“这是一个标签”,JLabel.CENTER);
label.addComponentListener(this);
JCheckBox checkbox=newjcheckbox(“标签可见”,true);
复选框.addItemListener(此);
复选框.addComponentListener(此);
JPanel面板=新JPanel(新网格布局(1,2));
面板。添加(标签);
面板。添加(复选框);
panel.addComponentListener(此);
frame=新的JFrame(“ComponentEventDemo”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(滚动窗格,BorderLayout.CENTER);
框架。添加(面板、边框布局。第_页结束);
frame.pack();
frame.setVisible(true);
}
公共无效itemStateChanged(ItemEvent e){
如果(如getStateChange()==ItemEvent.SELECTED){
label.setVisible(true);
label.revalidate();
label.repaint();
}否则{
标签可见(假);
}
}
受保护的无效显示消息(字符串消息){
//如果文本区域尚未实现,以及
//我们让它画文本,它可能导致
//文本/AWT树死锁。我们的解决方案是
//以确保实现文本区域
//在尝试绘制文本之前。
//if(display.isShowing()){
显示.追加(消息+换行符);
display.setCaretPosition(display.getDocument().getLength());
//}
}
公共无效组件隐藏(组件事件e){
显示消息(例如getComponent().getClass().getName()+“---隐藏”);
}
公共无效组件已移动(组件事件e){
显示消息(例如getComponent().getClass().getName()+“--Moved”);
}
公共无效组件已恢复(组件事件e){
displayMessage(例如getComponent().getClass().getName()+“---已调整大小”);
}
显示的公共无效组件(组件事件e){
显示消息(如getComponent().getClass().getName()+“---显示”);
}
公共静态void main(字符串[]args){
javax.swing.SwingUtilities.invokeLater(ne)
public static class GroundFrame extends JFrame {
private boolean doResize = false;
public GroundFrame() throws HeadlessException {
setResizable(false);
getContentPane().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Point point = e.getPoint();
if (point.x >= getWidth() - 50) {
doResize = true;
}
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
if (doResize) {
setSize(e.getX(), getHeight());
doResize = false;
}
}
});
}
}
public static class GroundFrame extends JFrame {
private Timer timer;
private Dimension oldSize;
public GroundFrame() throws HeadlessException {
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
oldSize = null;
invalidate();
}
});
timer.setRepeats(false);
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
if (oldSize == null) {
oldSize = getSize();
timer.start();
} else {
setSize(oldSize);
timer.restart();
}
}
});
}
}
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameSizeAfterDrag extends JFrame {
//direction holds the position of drag
private int w = 0, h = 0, direction, startX = 0, startY = 0;
public JFrameSizeAfterDrag() {
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(new MouseAdapter() {
//so we can see if from where the user clikced is he increasing or decraesing size
@Override
public void mousePressed(MouseEvent me) {
super.mouseClicked(me);
startX = me.getX();
startY = me.getY();
System.out.println("Clicked: " + startX + "," + startY);
}
//when the mouse is relaeased set size
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
System.out.println("Mouse released");
if (direction == 1 || direction == 2 || direction == 5 || direction == 6) {
setSize(w, h);
} else {//this should move x and y by as much as the mouse moved then use setBounds(x,y,w,h);
setBounds(getX() - (startX - me.getX()), getY() - (startY - me.getY()), w, h);
}
validate();
}
});
addMouseMotionListener(new MouseAdapter() {
private boolean canResize;
//while dragging check direction of drag
@Override
public void mouseDragged(MouseEvent me) {
super.mouseDragged(me);
System.out.println("Dragging:" + me.getX() + "," + me.getY());
if (canResize && direction == 1) {//frame height change
if (startY > me.getY()) {//decrease in height
h -= 4;
} else {//increase in height
h += 4;
}
} else if (canResize && direction == 2) {//frame width change
if (startX > me.getX()) {//decrease in width
w -= 4;
} else {//increase in width
w += 4;
}
} else if (canResize && direction == 3) {//frame height change
if (startX > me.getX()) {//decrease in width
w += 4;
} else {//increase in width
w -= 4;
}
} else if (canResize && direction == 4) {//frame width change
if (startY > me.getY()) {//decrease in height
h += 4;
} else {//increase in height
h -= 4;
}
} else if (canResize && direction == 5) {//frame width and height change bottom right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
} /* Windows dont usually support reszing from top but if you want :) uncomment code in mouseMoved(..) also
else if (canResize && direction == 6) {//frame width and height change top left
if (startY > me.getY() && startX > me.getX()) {//decrease in height and with
h += 4;
w += 4;
} else {//increase in height and width
h -= 4;
w -= 4;
}
} else if (canResize && direction == 8) {//frame width and height change top right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
*/ else if (canResize && direction == 7) {//frame width and height change bottom left
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
}
@Override
public void mouseMoved(MouseEvent me) {
super.mouseMoved(me);
if (me.getY() >= getHeight() - 10 && me.getX() >= getWidth() - 10) {//close to bottom and right side of frame show south east cursor and allow height witdh simaltneous increase/decrease
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
direction = 5;
} /*Windows dont usually support reszing from top but if you want :) uncomment code in mouseDragged(..) too
else if (me.getY() <= 28 && me.getX() <= 28) {//close to top side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
direction = 6;
} else if (me.getY() <= 28 && me.getX() >= getWidth() - 10) {//close to top and right side of frame show north east cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
direction = 8;
}
*/ else if (me.getY() >= getHeight() - 10 && me.getX() <= 10) {//close to bottom side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
direction = 7;
} else if (me.getY() >= getHeight() - 10) {//close to bottom of frame show south resize cursor and only allow increase height
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
direction = 1;
} else if (me.getX() >= getWidth() - 10) {//close to right side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
direction = 2;
} else if (me.getX() <= 10) {//close to left side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
direction = 3;
} else if (me.getY() <= 28) {//close to top side of frame show east cursor and only allow increase height
// System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
direction = 4;
} else {
canResize = false;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
// System.out.println("resize not allowed");
}
}
});
//just so GUI is visible and not small
add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
pack();
setVisible(true);
}
@Override
public void setVisible(boolean bln) {
super.setVisible(bln);
w = getWidth();
h = getHeight();
}
public static void main(String[] args) {
/**
* Create GUI and components on Event-Dispatch-Thread
*/
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JFrameSizeAfterDrag();
}
});
}
}
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class JFrameSizeAfterDrag2 extends JFrame {
private Timer timer;
private JPanel panel2;
boolean canResize = true,firstTime = true;
public JFrameSizeAfterDrag2() {
super("GradientTranslucentWindow");
setBackground(new Color(0, 0, 0, 0));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new JPanel(null) {//contentpane layout is null only
@Override
protected void paintComponent(Graphics g) {
Paint p = new GradientPaint(0.0f, 0.0f, new Color(0, 0, 0, 0), 0.0f, getHeight(), new Color(0, 0, 0, 0), true);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
});
panel2 = new JPanel();
panel2.setBackground(Color.black);
getContentPane().add(panel2);
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
if (canResize) {
resizePanel(getContentPane().getSize());
}
}
});
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
timer = new Timer(50, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
canResize = false;
} else {
canResize = true;
if (firstTime == true) {
firstTime = false;
resizePanel(getContentPane().getSize());
}
}
}
});
timer.setRepeats(false);
timer.start();
}
});
pack();
}
public void resizePanel(Dimension dim) {
panel2.setBounds(0, 0, dim.width, dim.height);
revalidate();
}
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported = gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!isPerPixelTranslucencySupported) {
System.out.println("Per-pixel translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrameSizeAfterDrag2 gtw = new JFrameSizeAfterDrag2();
gtw.setVisible(true);
}
});
}
}