我正在编程扩展JComboBox的自定义组件。我的问题是,如果我要添加或删除项目,PopupMenu不会实现其大小。因此,例如,列表中有2个项目,但是如果在PopupMenu中还有2个“空”项目之前还有4个项目。
我发现的唯一解决方法是(在JIntelligentComboBox.java第213行中)
this.setPopupVisible(false); this.setPopupVisible(true);
但结果将是闪烁的PopupMenu :-(
那么我还能做些什么来刷新/重画PopupMenu而不会闪烁呢?
对于测试:组件和一些测试程序
要产生我的问题,您可以例如:
提前致谢
编辑:我的目标是一个ComboBox,其行为类似于例如Firefox或Chrome中的adressbar,我想显示包含类型字符的PopupMenu的所有项目。
cboxtester.java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class cboxtester extends JFrame {
private DefaultComboBoxModel dcm = new DefaultComboBoxModel(new Object[][] {new Object[] {"Mittagessen", "", 0},
new Object[] {"Essen", "", 0},
new Object[] {"Frühstück", "", 0},
new Object[] {"Abendessen", "", 0}});
private JIntelligentComboBox icb = new JIntelligentComboBox(dcm);
private cboxtester(){
this.add(icb, BorderLayout.CENTER);
this.add(new JButton("bla"), BorderLayout.EAST);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
cboxtester cbt = new cboxtester();
}
}
JIntelligentComboBox.java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Vector;
import javax.swing.ComboBoxEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultRowSorter;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.MutableComboBoxModel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.plaf.metal.MetalComboBoxEditor;
public class JIntelligentComboBox extends JComboBox {
private ArrayList<Object> itemBackup = new ArrayList<Object>();
/** Initisiert die JIntelligentComboBox */
private void init(){
class searchComboBoxEditor extends BasicComboBoxEditor {
public searchComboBoxEditor(){
super();
}
@Override
public void setItem(Object anObject){
if (anObject == null) {
super.setItem(anObject);
} else {
Object[] o = (Object[]) anObject;
super.setItem(o[0]);
}
}
@Override
public Object getItem(){
return new Object[]{super.getItem(), super.getItem(), 0};
}
}
this.setEditor(new searchComboBoxEditor());
this.setEditable(true);
class searchRenderer extends BasicComboBoxRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus){
if (index == 0) {
setText("");
this.setPreferredSize(new Dimension(1, 1));
return this;
}
this.setPreferredSize(new Dimension(160, 17));
if (index == list.getModel().getSize() - 1) {
this.setBorder(new EmptyBorder(0, 3, 1, 3));
} else {
this.setBorder(new EmptyBorder(0, 3, 0, 3));
}
Object[] v = (Object[]) value;
//System.out.println(v[0]);
this.setFont(new Font("Arial", Font.PLAIN, 12));
this.setBackground(Color.white);
String s = (String) v[0];
String lowerS = s.toLowerCase();
String sf = (String) v[1];
String lowerSf = sf.toLowerCase();
ArrayList<String> notMatching = new ArrayList<String>();
if (!sf.equals("")){
int fs = -1;
int lastFs = 0;
while ((fs = lowerS.indexOf((String) lowerSf, (lastFs == 0) ? -1 : lastFs)) > -1) {
notMatching.add(s.substring(lastFs, fs));
lastFs = fs + sf.length();
//System.out.println(fs+sf.length());
}
notMatching.add(s.substring(lastFs));
//System.out.println(notMatching);
}
String html = "";
if (notMatching.size() > 1) {
html = notMatching.get(0);
int start = html.length();
int sfl = sf.length();
for (int i = 1; i < notMatching.size(); i++) {
String t = notMatching.get(i);
html += "<b style=\"color: black;\">" + s.substring(start, start + sfl) + "</b>" + t;
start += sfl + t.length();
}
}
System.out.println(index + html);
this.setText("<html><head></head><body style=\"color: gray;\">" + html + "</body></head>");
return this;
}
}
this.setRenderer(new searchRenderer());
// leeres Element oben einfügen
int size = this.getModel().getSize();
Object[] tmp = new Object[this.getModel().getSize()];
for (int i = 0; i < size; i++) {
tmp[i] = this.getModel().getElementAt(i);
itemBackup.add(tmp[i]);
}
this.removeAllItems();
this.getModel().addElement(new Object[]{"", "", 0});
for (int i = 0; i < tmp.length; i++) {
this.getModel().addElement(tmp[i]);
}
// keylistener hinzufügen
this.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
searchAndListEntries(((JTextField)JIntelligentComboBox.this.getEditor().getEditorComponent()).getText());
//System.out.println(((JTextField)JIntelligentComboBox.this.getEditor().getEditorComponent()).getText());
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
});
}
public JIntelligentComboBox(){
super();
}
public JIntelligentComboBox(MutableComboBoxModel aModel){
super(aModel);
init();
}
public JIntelligentComboBox(Object[] items){
super(items);
init();
}
public JIntelligentComboBox(Vector<?> items){
super(items);
init();
}
@Override
public MutableComboBoxModel getModel(){
return (MutableComboBoxModel) super.getModel();
}
private void searchAndListEntries(Object searchFor){
ArrayList<Object> found = new ArrayList<Object>();
//System.out.println("sf: "+searchFor);
for (int i = 0; i < this.itemBackup.size(); i++) {
Object tmp = this.itemBackup.get(i);
if (tmp == null || searchFor == null) continue;
Object[] o = (Object[]) tmp;
String s = (String) o[0];
if (s.matches("(?i).*" + searchFor + ".*")){
found.add(new Object[]{((Object[])tmp)[0], searchFor, ((Object[])tmp)[2]});
}
}
this.removeAllItems();
this.getModel().addElement(new Object[] {searchFor, searchFor, 0});
for (int i = 0; i < found.size(); i++) {
this.getModel().addElement(found.get(i));
}
this.setPopupVisible(true);
}
}
以下解决方案的基础是每次调用时都要调整弹出窗口的大小searchAndListRoutine
。您需要考虑的是,当弹出窗口显示在父框架的边界之外时,该弹出窗口可以显示在其自己的窗口中,或者可以将其显示在父框架的分层窗格中:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
import javax.swing.plaf.basic.*;
public class JIntelligentComboBox extends JComboBox {
private ArrayList<Object> itemBackup = new ArrayList<Object>();
/** Initisiert die JIntelligentComboBox */
private void init(){
class searchComboBoxEditor extends BasicComboBoxEditor {
public searchComboBoxEditor(){
super();
}
@Override
public void setItem(Object anObject){
if (anObject == null) {
super.setItem(anObject);
} else {
Object[] o = (Object[]) anObject;
super.setItem(o[0]);
}
}
@Override
public Object getItem(){
return new Object[]{super.getItem(), super.getItem(), 0};
}
}
this.setEditor(new searchComboBoxEditor());
this.setEditable(true);
class searchRenderer extends BasicComboBoxRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus){
if (index == 0) {
setText("");
this.setPreferredSize(new Dimension(1, 1));
return this;
}
this.setPreferredSize(new Dimension(160, 17));
if (index == list.getModel().getSize() - 1) {
this.setBorder(new EmptyBorder(0, 3, 1, 3));
} else {
this.setBorder(new EmptyBorder(0, 3, 0, 3));
}
Object[] v = (Object[]) value;
//System.out.println(v[0]);
this.setFont(new Font("Arial", Font.PLAIN, 12));
this.setBackground(Color.white);
String s = (String) v[0];
String lowerS = s.toLowerCase();
String sf = (String) v[1];
String lowerSf = sf.toLowerCase();
ArrayList<String> notMatching = new ArrayList<String>();
if (!sf.equals("")){
int fs = -1;
int lastFs = 0;
while ((fs = lowerS.indexOf((String) lowerSf, (lastFs == 0) ? -1 : lastFs)) > -1) {
notMatching.add(s.substring(lastFs, fs));
lastFs = fs + sf.length();
//System.out.println(fs+sf.length());
}
notMatching.add(s.substring(lastFs));
//System.out.println(notMatching);
}
String html = "";
if (notMatching.size() > 1) {
html = notMatching.get(0);
int start = html.length();
int sfl = sf.length();
for (int i = 1; i < notMatching.size(); i++) {
String t = notMatching.get(i);
html += "<b style=\"color: black;\">" + s.substring(start, start + sfl) + "</b>" + t;
start += sfl + t.length();
}
}
this.setText("<html><head></head><body style=\"color: gray;\">" + html + "</body></head>");
return this;
}
}
this.setRenderer(new searchRenderer());
//
int size = this.getModel().getSize();
Object[] tmp = new Object[this.getModel().getSize()];
for (int i = 0; i < size; i++) {
tmp[i] = this.getModel().getElementAt(i);
itemBackup.add(tmp[i]);
}
this.removeAllItems();
this.getModel().addElement(new Object[]{"", "", 0});
for (int i = 0; i < tmp.length; i++) {
this.getModel().addElement(tmp[i]);
}
//
this.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
searchAndListEntries(((JTextField)JIntelligentComboBox.this.getEditor().getEditorComponent()).getText());
//System.out.println(((JTextField)JIntelligentComboBox.this.getEditor().getEditorComponent()).getText());
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
});
}
public JIntelligentComboBox(){
super();
}
public JIntelligentComboBox(MutableComboBoxModel aModel){
super(aModel);
init();
}
public JIntelligentComboBox(Object[] items){
super(items);
init();
}
public JIntelligentComboBox(Vector<?> items){
super(items);
init();
}
@Override
public MutableComboBoxModel getModel(){
return (MutableComboBoxModel) super.getModel();
}
private void searchAndListEntries(Object searchFor){
ArrayList<Object> found = new ArrayList<Object>();
//System.out.println("sf: "+searchFor);
for (int i = 0; i < this.itemBackup.size(); i++) {
Object tmp = this.itemBackup.get(i);
if (tmp == null || searchFor == null) continue;
Object[] o = (Object[]) tmp;
String s = (String) o[0];
if (s.matches("(?i).*" + searchFor + ".*")){
found.add(new Object[]{((Object[])tmp)[0], searchFor, ((Object[])tmp)[2]});
}
}
this.removeAllItems();
this.getModel().addElement(new Object[] {searchFor, searchFor, 0});
for (int i = 0; i < found.size(); i++) {
this.getModel().addElement(found.get(i));
}
//this.setPopupVisible(true);
int size = this.getModel().getSize() - 1;
System.out.println("Elements: " + size);
if (size == 0)
{
this.setPopupVisible( false );
return;
}
this.setPopupVisible(true);
BasicComboPopup popup =
(BasicComboPopup)this.getAccessibleContext().getAccessibleChild(0);
Window popupWindow = SwingUtilities.windowForComponent(popup);
Window comboWindow = SwingUtilities.windowForComponent(this);
if (comboWindow.equals(popupWindow))
{
Component c = popup.getParent();
Dimension d = c.getPreferredSize();
c.setSize(d);
}
else
{
popupWindow.pack();
}
}
}
一个问题是,当组合框字段为空时,模型包含4个条目。我想这与您的匹配逻辑有关。
问题内容: 我将按钮放在带有GridLayout的JPane中。然后,我使用BoxLayout.Y_AXIS将JPanel放入另一个JPanel中。我希望GridLayout中的按钮为正方形。我使用tmp.setSize(30,30),它不起作用。我也尝试使用,但我不知道X和Y是什么。那么,做这些东西的正确方法是什么? 添加: 我仍然无法解决问题。这是我正在尝试执行的代码: 问题是Java试图使宽
我有一个JFrame,我已经将布局设置到GroupLayout。 我添加了两个Jpanel即workingPanel(红色)和backgroundPanel(绿色)。 代码是`import javax.swing.;导入java.awt; 请帮帮我。
我想在内部设置一个的。 我试着用 但这不起作用。我怎么能这么做?
我使用的是SpringBoot2.0。3释放。我想增加HikariCP的最大池大小,默认情况下为10。 我试着在带有 spring.datasource.hikari.maximum-池-大小=200 但是它不起作用,因为在日志中它仍然显示最大池大小为10。 我想改变的原因是,我不知怎么地达到了登台的极限,我不知道是什么原因造成的。
我正在使用JHipster开发基于Spring Boot和AngularJS的应用程序。我的问题是如何设置上传文件的最大大小? 如果我试图上传到大文件,我会在控制台中获得以下信息: 和状态为500的服务器响应。 怎么设置?