gpt4 book ai didi

java - 向 JPopupMenu 添加垂直滚动?

转载 作者:搜寻专家 更新时间:2023-10-30 19:48:29 25 4
gpt4 key购买 nike

我想添加一种方法来滚动浏览 JPopupMenu 中的菜单项,就像滚动浏览 JComboBox 中的项目列表一样。

假设我有 10 个菜单项。我想一次只显示 5 个菜单项,我会在 JPopupMenu 的底部或顶部使用垂直滚动按钮来显示未列出的菜单项并隐藏那些我刚看到。

这可能吗?我正在使用 JIDE Software 的 JideSplitButton,单击它会显示 JPopupMenu。我试图保持放置 JideSplitButton 的命令栏的外观,所以我不想用 JComboBox 替换它,除非我真的有到。

最佳答案

这是我使用滚动条创建的版本。这只是一个简单的示例,因此请根据需要进行调整:

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;

public class JScrollPopupMenu extends JPopupMenu {
protected int maximumVisibleRows = 10;

public JScrollPopupMenu() {
this(null);
}


public JScrollPopupMenu(String label) {
super(label);
setLayout(new ScrollPopupMenuLayout());

super.add(getScrollBar());
addMouseWheelListener(new MouseWheelListener() {
@Override public void mouseWheelMoved(MouseWheelEvent event) {
JScrollBar scrollBar = getScrollBar();
int amount = (event.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL)
? event.getUnitsToScroll() * scrollBar.getUnitIncrement()
: (event.getWheelRotation() < 0 ? -1 : 1) * scrollBar.getBlockIncrement();

scrollBar.setValue(scrollBar.getValue() + amount);
event.consume();
}
});
}

private JScrollBar popupScrollBar;
protected JScrollBar getScrollBar() {
if(popupScrollBar == null) {
popupScrollBar = new JScrollBar(JScrollBar.VERTICAL);
popupScrollBar.addAdjustmentListener(new AdjustmentListener() {
@Override public void adjustmentValueChanged(AdjustmentEvent e) {
doLayout();
repaint();
}
});

popupScrollBar.setVisible(false);
}

return popupScrollBar;
}

public int getMaximumVisibleRows() {
return maximumVisibleRows;
}

public void setMaximumVisibleRows(int maximumVisibleRows) {
this.maximumVisibleRows = maximumVisibleRows;
}

public void paintChildren(Graphics g){
Insets insets = getInsets();
g.clipRect(insets.left, insets.top, getWidth(), getHeight() - insets.top - insets.bottom);
super.paintChildren(g);
}

protected void addImpl(Component comp, Object constraints, int index) {
super.addImpl(comp, constraints, index);

if(maximumVisibleRows < getComponentCount()-1) {
getScrollBar().setVisible(true);
}
}

public void remove(int index) {
// can't remove the scrollbar
++index;

super.remove(index);

if(maximumVisibleRows >= getComponentCount()-1) {
getScrollBar().setVisible(false);
}
}

public void show(Component invoker, int x, int y){
JScrollBar scrollBar = getScrollBar();
if(scrollBar.isVisible()){
int extent = 0;
int max = 0;
int i = 0;
int unit = -1;
int width = 0;
for(Component comp : getComponents()) {
if(!(comp instanceof JScrollBar)) {
Dimension preferredSize = comp.getPreferredSize();
width = Math.max(width, preferredSize.width);
if(unit < 0){
unit = preferredSize.height;
}
if(i++ < maximumVisibleRows) {
extent += preferredSize.height;
}
max += preferredSize.height;
}
}

Insets insets = getInsets();
int widthMargin = insets.left + insets.right;
int heightMargin = insets.top + insets.bottom;
scrollBar.setUnitIncrement(unit);
scrollBar.setBlockIncrement(extent);
scrollBar.setValues(0, heightMargin + extent, 0, heightMargin + max);

width += scrollBar.getPreferredSize().width + widthMargin;
int height = heightMargin + extent;

setPopupSize(new Dimension(width, height));
}

super.show(invoker, x, y);
}

protected static class ScrollPopupMenuLayout implements LayoutManager{
@Override public void addLayoutComponent(String name, Component comp) {}
@Override public void removeLayoutComponent(Component comp) {}

@Override public Dimension preferredLayoutSize(Container parent) {
int visibleAmount = Integer.MAX_VALUE;
Dimension dim = new Dimension();
for(Component comp :parent.getComponents()){
if(comp.isVisible()) {
if(comp instanceof JScrollBar){
JScrollBar scrollBar = (JScrollBar) comp;
visibleAmount = scrollBar.getVisibleAmount();
}
else {
Dimension pref = comp.getPreferredSize();
dim.width = Math.max(dim.width, pref.width);
dim.height += pref.height;
}
}
}

Insets insets = parent.getInsets();
dim.height = Math.min(dim.height + insets.top + insets.bottom, visibleAmount);

return dim;
}

@Override public Dimension minimumLayoutSize(Container parent) {
int visibleAmount = Integer.MAX_VALUE;
Dimension dim = new Dimension();
for(Component comp : parent.getComponents()) {
if(comp.isVisible()){
if(comp instanceof JScrollBar) {
JScrollBar scrollBar = (JScrollBar) comp;
visibleAmount = scrollBar.getVisibleAmount();
}
else {
Dimension min = comp.getMinimumSize();
dim.width = Math.max(dim.width, min.width);
dim.height += min.height;
}
}
}

Insets insets = parent.getInsets();
dim.height = Math.min(dim.height + insets.top + insets.bottom, visibleAmount);

return dim;
}

@Override public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();

int width = parent.getWidth() - insets.left - insets.right;
int height = parent.getHeight() - insets.top - insets.bottom;

int x = insets.left;
int y = insets.top;
int position = 0;

for(Component comp : parent.getComponents()) {
if((comp instanceof JScrollBar) && comp.isVisible()) {
JScrollBar scrollBar = (JScrollBar) comp;
Dimension dim = scrollBar.getPreferredSize();
scrollBar.setBounds(x + width-dim.width, y, dim.width, height);
width -= dim.width;
position = scrollBar.getValue();
}
}

y -= position;
for(Component comp : parent.getComponents()) {
if(!(comp instanceof JScrollBar) && comp.isVisible()) {
Dimension pref = comp.getPreferredSize();
comp.setBounds(x, y, width, pref.height);
y += pref.height;
}
}
}
}
}

关于java - 向 JPopupMenu 添加垂直滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9288350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com