可以显示横向ScrollBar的下拉框ComboBox

来源:互联网 发布:杰克逊总统知乎 编辑:程序博客网 时间:2024/05/18 02:18
这个不知道有没有人写过.
有点限制, 因为替换了UI, 所以只能在Metal下看才不会有异样的感觉.
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
/**
 * Created at 2006-7-25 13:06:10<br>
 * 下拉延长的下拉框
 
*/

@SuppressWarnings(
"serial")
public class ExtendedComboBox extends JComboBox {
 
public ExtendedComboBox() {
 }

 
/**
  * 
@param aModel
  
*/

 
public ExtendedComboBox(ComboBoxModel aModel) {
  
super(aModel);
 }

 
/**
  * 
@param items
  
*/

 
public ExtendedComboBox(Object[] items) {
  
super(items);
 }

 
/**
  * 
@param items
  
*/

 
public ExtendedComboBox(Vector<?> items) {
  
super(items);
 }

 
/**
  * (非 Javadoc)
  *
  * 
@see javax.swing.JComboBox#updateUI()
  
*/

 @Override
 
public void updateUI() {
  setUI(
new ExtendedComboBoxUI());
 }

 
/**
  * (非 Javadoc)<br>
  * 如果需要修改最适合尺寸, 重写此方法
  *
  * 
@see javax.swing.JComponent#getPreferredSize()
  
*/

 @Override
 
public Dimension getPreferredSize() {
  Dimension dim 
= super.getPreferredSize();
  dim.width 
= 120;
  
return dim;
 }

}

 
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;
/**
 * Created at 2006-7-25 13:09:13<br>
 * 延长的ComboBoxUI
 
*/

public class ExtendedComboBoxUI extends MetalComboBoxUI {
 
public static ComponentUI createUI(JComponent c) {
  
return new ExtendedComboBoxUI();
 }

 
/**
  * (非 Javadoc)
  *
  * 
@see javax.swing.plaf.basic.BasicComboBoxUI#createPopup()
  
*/

 
protected ComboPopup createPopup() {
  ExtendedComboPopup popup 
= new ExtendedComboPopup(comboBox);
  popup.getAccessibleContext().setAccessibleParent(comboBox);
  
return popup;
 }

 
public ComboPopup getPopup() {
  
return popup;
 }

}

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ScrollPaneConstants;
import javax.swing.plaf.basic.BasicComboPopup;
/**
 * Created at 2006-7-25 13:07:04<br>
 * 延长的下拉框弹出菜单
 
*/

@SuppressWarnings(
"serial")
public class ExtendedComboPopup extends BasicComboPopup {
 
private int width = -1;
 
private int maxWidth = 300;
 
/**
  * 
@param combo
  
*/

 
public ExtendedComboPopup(JComboBox combo) {
  
super(combo);
 }

 
/**
  * (非 Javadoc)
  *
  * 
@see javax.swing.plaf.basic.BasicComboPopup#createScroller()
  
*/

 
protected JScrollPane createScroller() {
  
return new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
 }

 
/**
  * (非 Javadoc)
  *
  * 
@see java.awt.Component#show()
  
*/

 @SuppressWarnings(
"deprecation")
 
public void show() {
  
// todo: if not set the width of popup menu,
  
// then set the default width(width of combobox)
  Dimension popupSize = comboBox.getSize();
  Insets insets 
= getInsets();
  popupSize.setSize(popupSize.width 
- (insets.right + insets.left),
    getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
  
// 计算最大项目的宽度
  int maxWidthOfCell = calcPreferredWidth();
  width 
= maxWidthOfCell;
  
if (width > this.maxWidth)
   width 
= this.maxWidth;
  
if (width < this.comboBox.getWidth())
   width 
= comboBox.getWidth();
  
if (maxWidthOfCell > width) {
   
// 显示竖滚动条
   
// 需要增加高度
   popupSize.height += scroller.getHorizontalScrollBar().getPreferredSize().height;
  }

  Rectangle popupBounds 
= computePopupBounds(0, comboBox.getBounds().height, width,
    popupSize.height);
  scroller.setMaximumSize(popupBounds.getSize());
  scroller.setPreferredSize(popupBounds.getSize());
  scroller.setMinimumSize(popupBounds.getSize());
  list.invalidate();
  syncListSelectionWithComboBoxSelection();
  list.ensureIndexIsVisible(list.getSelectedIndex());
  setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
  show(comboBox, popupBounds.x, popupBounds.y);
 }

 
/**
  * 计算当前的最适合宽度
  *
  * 
@return
  
*/

 
private int calcPreferredWidth() {
  
int width = 0;
  ListCellRenderer renderer 
= list.getCellRenderer();
  
for (int index = 0, count = list.getModel().getSize(); index < count; index++{
   Object element 
= list.getModel().getElementAt(index);
   Component comp 
= renderer.getListCellRendererComponent(list, element, index, false,
     
false);
   Dimension dim 
= comp.getPreferredSize();
   
if (dim.width > width)
    width 
= dim.width;
  }

  
return width;
 }

 
void syncListSelectionWithComboBoxSelection() {
  
int selectedIndex = comboBox.getSelectedIndex();
  
if (selectedIndex == -1{
   list.clearSelection();
  }
 else {
   list.setSelectedIndex(selectedIndex);
  }

 }

 
public void setPopupWidth(int width) {
  
this.width = width;
 }

}
其实重写UI的原因就是因为需要重写这个Popup. Java原先的Popup是不显示横向ScrollBar的. 而且更改了ScrollBar的显示原则以后, 那么尺寸也必须重新计算了.
 
原创粉丝点击