我有一个带有JSplitPane的Java GUI程序,用于划分内容。 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(下)。运行此命令时,第一次将滑块向右拖动时,它将“快照”到长标签的末尾,然后在那里固定。我相信这是由长标签触发的。如果缩短标签,则滑块上的运动范围会更大。那么,这是错误还是预期的行为?
public class SplitPaneTest extends javax.swing.JFrame {
public SplitPaneTest() {
initComponents();
}
private void initComponents() {
jSplitPane1 = new javax.swing.JSplitPane();
jLabel1 = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jSplitPane1.setDividerLocation(450);
jSplitPane1.setName("jSplitPane1");
jLabel1.setText("right side");
jLabel1.setName("jLabel1");
jSplitPane1.setRightComponent(jLabel1);
jPanel1.setName("jPanel1");
jLabel2.setText("left side asd adsf asdf asdf asdf sadf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdfa end");
jLabel2.setName("jLabel2");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel2)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel2)
.addContainerGap(420, Short.MAX_VALUE))
);
jSplitPane1.setLeftComponent(jPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1)
);
pack();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new SplitPaneTest().setVisible(true);
}
});
}
protected javax.swing.JLabel jLabel1;
protected javax.swing.JLabel jLabel2;
protected javax.swing.JPanel jPanel1;
protected javax.swing.JSplitPane jSplitPane1;
}
最佳答案
我花了很多时间试图达到
SSCCE,但无法这样做
。
请什么? SSCCE最多5分钟
现在仍然有两个问题
也有SplitPaneUI
的定义,因为if (ui instanceof BasicSplitPaneUI) {
可以返回漂亮的false
并附上原因说明,其中添加了MouseMotionListener
EDIT_1st。
JSplitPane的左侧是带有许多标签的JTabbedPane
-非常复杂的布局。当左侧达到一定程度的复杂度时,拖动分隔线以移动分隔线的位置
可以使用更长的时间,但是我仍然可以通过显式设置来移动分隔线
那个地点。
wild shot in the dark == you need to know
调整JSplitPane容器大小时分配空间的重量
拆分窗格的控件控制拆分时分隔符的行为
窗格已调整大小。如果权重为0,则将所有多余的空间分配给
右侧或底部组件。如果权重为1,则所有多余空间为
赋予左侧或顶部组件。权重.3指定
左侧或顶部组件将获得额外空间的三分之一。重量
还可确定孩子在拆分大小时如何失去空间
窗格减少。例如,权重为0表示左侧或顶部
组件不会丢失任何空间。
砝码还控制分隔线的起始位置。对于
例如,如果权重为.5,则分隔线位于中间。
复制
// Create a left-right split pane
JSplitPane pane = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT, leftComponent, rightComponent);
// Get current weight
double weight = pane.getResizeWeight(); // 0.0 by default
// Keep the size of the right component constant
weight = 1D;
pane.setResizeWeight(weight);
// Split the space evenly
weight = .5D;
pane.setResizeWeight(weight);
EDIT_2nd。
您忘了告诉我们,在Nimbus中,分隔线出现了完全闪烁,不是由其他标准L&F引起的
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;
}
}