Java JSplitPane分隔器拖动不适用于复杂布局
我有一个Java GUI程序,其中包含一个JSplitPane,用于划分内容。JSplitPane的左侧是一个JTabbedPane,有许多选项卡,这是一个非常复杂的布局。当左侧达到一定的复杂程度时,拖动分隔器以移动分隔器位置不再有效,但我仍然可以通过显式设置位置来移动分隔器。(如果有必要,我正在使用Nimbus LAF。) 这似乎不仅仅是左边标签的数量。我在左侧包含的某些选项卡使其停止工作,而其他选项卡则可以 有人碰到过这个吗 我可以通过在我的JSplitPane子类上添加一个hack变通方法来解决这个问题Java JSplitPane分隔器拖动不适用于复杂布局,java,swing,jsplitpane,Java,Swing,Jsplitpane,我有一个Java GUI程序,其中包含一个JSplitPane,用于划分内容。JSplitPane的左侧是一个JTabbedPane,有许多选项卡,这是一个非常复杂的布局。当左侧达到一定的复杂程度时,拖动分隔器以移动分隔器位置不再有效,但我仍然可以通过显式设置位置来移动分隔器。(如果有必要,我正在使用Nimbus LAF。) 这似乎不仅仅是左边标签的数量。我在左侧包含的某些选项卡使其停止工作,而其他选项卡则可以 有人碰到过这个吗 我可以通过在我的JSplitPane子类上添加一个hack变通方法
public void enableDividerWorkaround() {
javax.swing.plaf.basic.BasicSplitPaneUI l_ui = (javax.swing.plaf.basic.BasicSplitPaneUI) getUI();
BasicSplitPaneDivider l_divider = l_ui.getDivider();
l_divider.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
Dimension l_pane_size = getSize();
if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
int l_new_loc = getDividerLocation() + e.getX();
if (l_new_loc >= 0 && l_new_loc <= l_pane_size.width) {
setDividerLocation(l_new_loc);
}
} else {
int l_new_loc = getDividerLocation() + e.getY();
if (l_new_loc >= 0 && l_new_loc <= l_pane_size.height) {
setDividerLocation(l_new_loc);
}
}
}
});
}
我花了相当多的时间试图达到有一个 但SSCCE未能这样做
- 请问什么???最多5分钟
- 现在还有两个问题
- 也有
的定义吗,因为SplitPaneUI
可以返回相当多的if(BasicSplitPaneUI的ui实例){
false
- 其中添加了MouseMotionListener的原因说明
首先编辑 JSplitPane的左侧是一个JTabbedPane,其中有许多选项卡 -一个非常复杂的布局。当左侧达到一定的复杂程度时,拖动分隔符以移动分隔符位置no 工作时间更长,但我仍然可以通过显式设置来移动分隔符 地点
编辑第2页 你忘了告诉我们,在Nimbus中,是否有一个完全闪烁的除法器,而不是由标准L&F的其余部分引起的
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseMotionAdapter;
导入javax.swing.BorderFactory;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JSplitPane;
导入javax.swing.JTable;
导入javax.swing.plaf.basic.BasicSplitPaneVider;
导入javax.swing.plaf.basic.BasicSplitPaneUI;
公共类JSplitPaneToy{
私人股份有限公司;
公共JSplitPaneToy(){
sp=新的JSplitPane(JSplitPane.HORIZONTAL_SPLIT,makePanel(),makePanel());
/*SplitPaneUI ui=sp.getUI();
if(基本CSplitPaneUI实例){
((BasicSplitPaneUI)ui.getDivider().setBorder(null);
}*/
BasicSplitPaneUI l_ui=(BasicSplitPaneUI)sp.getUI();
BasicSplitPaneDivider l_divider=l_ui.getDivider();
l_divider.addMouseMotionListener(新的MouseMotionAdapter(){
@凌驾
公共无效鼠标标记(鼠标事件e){
尺寸l_窗格_size=sp.getSize();
if(sp.getOrientation()==JSplitPane.HORIZONTAL_SPLIT){
int l_new_loc=sp.getDividerLocation()+e.getX();
如果(l_new_loc>=0&&l_new_loc=0&&l_new_loc,这似乎是故意的行为。在javax.swing.plaf.basic.BasicSplitPaneVider.DragController的构造函数中找到以下代码:
minX = leftC.getMinimumSize().width;
后来在同一节课上
/**
* Returns the new position to put the divider at based on
* the passed in MouseEvent.
*/
protected int positionForMouseEvent(MouseEvent e) {
int newX = (e.getSource() == BasicSplitPaneDivider.this) ?
(e.getX() + getLocation().x) : e.getX();
newX = Math.min(maxX, Math.max(minX, newX - offset));
return newX;
}
因此,基本UI似乎有意不让您拖动分隔符,从而使左侧小于其最小大小
在我的情况下,这种行为不符合我的需要,所以我的小解决方案是必要的。An会在这里提供极大的帮助。SSCE中添加了MouseMotionListener,并描述了为什么会添加MouseMotionListener。请问SplitPaneUI tooI有没有定义我花了相当多的时间尝试使用SSCE,但未能做到。我不要认为调整大小的权重适用于这里-JSplitPane没有调整大小,只是分隔器正在移动。我将在SSCCE上再做一次尝试。我想到了一种不同的方法来实现这一点,这可能会奏效。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
public class JSplitPaneToy {
private JSplitPane sp;
public JSplitPaneToy() {
sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, makePanel(), makePanel());
/*SplitPaneUI ui = sp.getUI();
if (ui instanceof BasicSplitPaneUI) {
((BasicSplitPaneUI) ui).getDivider().setBorder(null);
}*/
BasicSplitPaneUI l_ui = (BasicSplitPaneUI) sp.getUI();
BasicSplitPaneDivider l_divider = l_ui.getDivider();
l_divider.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
Dimension l_pane_size = sp.getSize();
if (sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
int l_new_loc = sp.getDividerLocation() + e.getX();
if (l_new_loc >= 0 && l_new_loc <= l_pane_size.width) {
sp.setDividerLocation(l_new_loc);
}
} else {
int l_new_loc = sp.getDividerLocation() + e.getY();
if (l_new_loc >= 0 && l_new_loc <= l_pane_size.height) {
sp.setDividerLocation(l_new_loc);
}
}
}
});
sp.setBorder(BorderFactory.createEmptyBorder());
/*sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
ui = sp.getUI();
if (ui instanceof BasicSplitPaneUI) {
((BasicSplitPaneUI) ui).getDivider().setBorder(null);
}
sp.setBorder(BorderFactory.createEmptyBorder());
sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
ui = sp.getUI();
if (ui instanceof BasicSplitPaneUI) {
((BasicSplitPaneUI) ui).getDivider().setBorder(null);
}
sp.setBorder(BorderFactory.createEmptyBorder());
sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
ui = sp.getUI();
if (ui instanceof BasicSplitPaneUI) {
((BasicSplitPaneUI) ui).getDivider().setBorder(null);
}
sp.setBorder(BorderFactory.createEmptyBorder());*/
JFrame frame = new JFrame("JSplitPane Toy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(sp);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new JSplitPaneToy();
}
});
}
private JScrollPane makePanel() {
JScrollPane pane = new JScrollPane(new JTable(
new Object[][]{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}}, new Object[]{1, 2, 3}) {
});
pane.setPreferredSize(new Dimension(200, 100));
return pane;
}
}
minX = leftC.getMinimumSize().width;
/**
* Returns the new position to put the divider at based on
* the passed in MouseEvent.
*/
protected int positionForMouseEvent(MouseEvent e) {
int newX = (e.getSource() == BasicSplitPaneDivider.this) ?
(e.getX() + getLocation().x) : e.getX();
newX = Math.min(maxX, Math.max(minX, newX - offset));
return newX;
}