DateComboBox öffnet sich hinter JTextarea.

Status
Nicht offen für weitere Antworten.

Balsi

Mitglied
Hy,

Ich habe folgendes, etwas verwirrendes Problem. Aus einem Open- Source Projekt habe ich mir DateComboBoxen gezogen. Diese öffnen einen kleinen Kalender als Drop- Down und der Benutzer kann dort das Datum auswählen.

So weit so gut.

Nun das Problem. Ich habe zwei solcher DateComboBoxen exakt gleich erstellt, beide befinden sich ein paar Pixel oberhalb derselben JTextare. Das Problem ist, dass sich der einer der beiden kleinen Kalender hinter der JTextare öffnet, wärend der andere wie gewollt den Kalender vor die JTextare schiebt.

Die Kombonenten habe ich beide nacheinander der contenPane zugeordnet.

Kennt jemand dieses Problem? Oder kennt jemand einen einfachen Weg, wie ich eine Komponentenreihenfolge angeben kann?

Vielen Dank für eure Zeit.

Mfg.
J. Balsiger
 
Hm, ich muss zugeben ich bin überhaupt nicht mit den Java Layout technischen Dingen vertraut, da ich normalerweise nur Web- Applikationen schreibe, aber ich versuchs mal:

- Der ganze Code ist in einer Klasse, welche von JFrame abgeleitet ist.

- ich hole mir hier eine content Pane:
contentPane = (JPanel)this.getContentPane();

- contentPane.setLayout(null); dieser Eintrag heisst wohl ich habe kein, oder ein Standartlayout.

- dieser contentPane adde ich dann die einzelnen Elemente:
z.B. addComponent(contentPane, comboStart, 130,300,50,22);

Ich hoffe dass sind die richtigen Antworten.

Vielen Dank für deine Bemühungen.

Mfg.
J. Balsiger
 
Ja, du verwendest kein Layout, was bedeutet das du alle Komponenten absolut plazieren musst (bad practise).
Mach bitte ein Screenshot deines Problems und poste den relevanten Code.
 
Das ist richtig, ich muss für jedes Element die genaue Platzierung angeben. Ist nur so was für die schnelle, wie gesagt, nicht mein Hauptgebiet.


Also, zuerst die Screens:

So soll es sein, resp. hier ist eine aufgeklapte dateComboBox zu sehen, welche über der JTextArea liegt.

http://img-up.net/?up=workingCorBNl.jpg


Und hier noch die aufgeklapte dateComboBox, welche hinter der JTextArea liegt:


http://img-up.net/?up=notWorking0XuV.jpg


Hier die einzelnen Code Abschnitte, welche interessant sein dürften:

Code:
private DateComboBox start;
private DateComboBox ende;
private DateComboBox erledigt;
private DateComboBox erstellDat;
private TextArea beschreibung;

...

beschreibung = new TextArea();
erledigt = new DateComboBox();
erstellDat = new DateComboBox();
start = new DateComboBox();
ende = new DateComboBox();

...

erledigt.setEditable(true);
erstellDat.setEditable(true);
start.setEditable(true);
ende.setEditable(true);

...

addComponent(contentPane, beschreibung, 130,390,819,100);
addComponent(contentPane, erstellDat, 846,360,102,22);
addComponent(contentPane, ende, 130,360,100,22);
addComponent(contentPane, start, 130,330,100,22);
addComponent(contentPane, erledigt, 846,240,102,22);

Das mit den Bildern hat leider nicht geklappt (ich hab nur kleine rote kreuze gesehen), desshalb der direkte link.
 
Hier noch die Klasse der DateComboBox. Wie gesagt Open Source:

Code:
package ch.zkb.resource.dateComboBox;

import java.awt.*;
import java.awt.event.*;
import java.util.Calendar;
import java.text.SimpleDateFormat;
 
import javax.swing.*;
 import javax.swing.event.PopupMenuListener;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.plaf.ComboBoxUI;
 import javax.swing.plaf.basic.ComboPopup;
 import javax.swing.plaf.metal.MetalComboBoxUI;
 import javax.swing.border.Border;
 import javax.swing.border.EtchedBorder;
 import javax.swing.border.EmptyBorder;
 
 import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
 import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;
 
 /**
  * @version 1.0 11/02/2000
  */ 
 
 //////////////////////////////////////////////////////////////
 
 public class DateComboBox extends JComboBox {
 
 //static java.util.ResourceBundle resource = java.util.ResourceBundle.getBundle("resources.Traduction")/*#BundleType=List*/;
 
     protected SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy");
     public void setDateFormat(SimpleDateFormat dateFormat) {
     this.dateFormat = dateFormat;
     }
     public void setSelectedItem(Object item) {
     // Could put extra logic here or in renderer when item is instanceof Date, Calendar, or String
 // Dont keep a list ... just the currently selected item
 removeAllItems(); // hides the popup if visible
 addItem(item);
     super.setSelectedItem(item);
     }
 
     public void updateUI() {
     ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
     if (cui instanceof MetalComboBoxUI) {
         cui = new MetalDateComboBoxUI();
     } else if (cui instanceof MotifComboBoxUI) {
         cui = new MotifDateComboBoxUI(); 
     } else if (cui instanceof WindowsComboBoxUI) {
         cui = new WindowsDateComboBoxUI();
    }
         setUI(cui);
     }
 
     // Inner classes are used purely to keep DateComboBox component in one file
 //////////////////////////////////////////////////////////////
 // UI Inner classes -- one for each supported Look and Feel
 //////////////////////////////////////////////////////////////
 
     class MetalDateComboBoxUI extends MetalComboBoxUI {
     protected ComboPopup createPopup() {
         return new DatePopup( comboBox );
     }
     }
 
     class WindowsDateComboBoxUI extends WindowsComboBoxUI {
     protected ComboPopup createPopup() {
         return new DatePopup( comboBox );
     }
     }
 
     class MotifDateComboBoxUI extends MotifComboBoxUI {
     protected ComboPopup createPopup() {
         return new DatePopup( comboBox );
     }
     }
 
     //////////////////////////////////////////////////////////////
 // DatePopup inner class
 //////////////////////////////////////////////////////////////
 
     class DatePopup implements ComboPopup, MouseMotionListener, 
                    MouseListener, KeyListener, PopupMenuListener {
     
     protected JComboBox comboBox;
     protected Calendar calendar;
     protected JPopupMenu popup;
     protected JLabel monthLabel;
     protected JPanel days = null;
     protected SimpleDateFormat monthFormat = new SimpleDateFormat("MMM yyyy");
 
     protected Color selectedBackground;
     protected Color selectedForeground;
     protected Color background;
     protected Color foreground;
 
     public DatePopup(JComboBox comboBox) {
         this.comboBox = comboBox;
         calendar = Calendar.getInstance();
         // check Look and Feel
 background = UIManager.getColor("ComboBox.background");
         foreground = UIManager.getColor("ComboBox.foreground");
         selectedBackground = UIManager.getColor("ComboBox.selectionBackground");
         selectedForeground = UIManager.getColor("ComboBox.selectionForeground");
 
         initializePopup();
     }
 
     //========================================
 // begin ComboPopup method implementations
 //
 public void show() {
         try {
         // if setSelectedItem() was called with a valid date, adjust the calendar
 calendar.setTime( dateFormat.parse( comboBox.getSelectedItem().toString() ) );
         } catch (Exception e) {}
         updatePopup(); 
        popup.show(comboBox, 0, comboBox.getHeight());
         }
     
     public void hide() {
         popup.setVisible(false);
    }

     protected JList list = new JList();
     public JList getList() {
         return list;
     }
 
     public MouseListener getMouseListener() {
         return this;
     }
 
     public MouseMotionListener getMouseMotionListener() {
         return this;
     }
 
   public KeyListener getKeyListener() {
         return this;
     }
 
     public boolean isVisible() {
         return popup.isVisible();
     }
     
     public void uninstallingUI() {
         popup.removePopupMenuListener(this);
     }
 
     //
 // end ComboPopup method implementations
 //======================================
 
 
 
     //===================================================================
 // begin Event Listeners
 //
 
     // MouseListener
 
     public void mousePressed( MouseEvent e ) {}
         public void mouseReleased( MouseEvent e ) {}
     // something else registered for MousePressed
 public void mouseClicked(MouseEvent e) {
             if ( !SwingUtilities.isLeftMouseButton(e) )
                 return;
             if ( !comboBox.isEnabled() )
                 return;
         if ( comboBox.isEditable() ) {
         comboBox.getEditor().getEditorComponent().requestFocus();
         } else {
         comboBox.requestFocus();
         }
         togglePopup();
     }
 
     protected boolean mouseInside = false;
     public void mouseEntered(MouseEvent e) {
         mouseInside = true;
     }
     public void mouseExited(MouseEvent e) {
         mouseInside = false;
     }
 
     // MouseMotionListener
 public void mouseDragged(MouseEvent e) {}
     public void mouseMoved(MouseEvent e) {}
            
     // KeyListener
 public void keyPressed(KeyEvent e) {}
     public void keyTyped(KeyEvent e) {} 
     public void keyReleased( KeyEvent e ) {
         if ( e.getKeyCode() == KeyEvent.VK_SPACE ||
         e.getKeyCode() == KeyEvent.VK_ENTER ) {
        togglePopup();
         }
     }
 
     /**
      * Variables hideNext and mouseInside are used to 
      * hide the popupMenu by clicking the mouse in the JComboBox
      */
     public void popupMenuCanceled(PopupMenuEvent e) {}
     protected boolean hideNext = false;
     public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
         hideNext = mouseInside;
     }
     public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
            
     //
 // end Event Listeners
 //=================================================================
 
     //===================================================================
 // begin Utility methods
 //
 
     protected void togglePopup() {
         if ( isVisible() || hideNext ) { 
         hide();
         } else {
        show();
         }
         hideNext = false;
     }
 
    //
 // end Utility methods
 //=================================================================
 
     // Note *** did not use JButton because Popup closes when pressed
 protected JLabel createUpdateButton(final int field, final int amount) {
         final JLabel label = new JLabel();
         final Border selectedBorder = new EtchedBorder();
         final Border unselectedBorder = new EmptyBorder(selectedBorder.getBorderInsets(new JLabel()));
         label.setBorder(unselectedBorder);
         label.setForeground(foreground);
         label.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
             calendar.add(field, amount);
             updatePopup();
             }
             public void mouseEntered(MouseEvent e) {
            label.setBorder(selectedBorder);
             }
             public void mouseExited(MouseEvent e) {
            label.setBorder(unselectedBorder);
             }
         });
         return label;
     }
 

     protected void initializePopup() {
         JPanel header = new JPanel(); // used Box, but it wasn't Opaque
 header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS));
         header.setBackground(background);
         header.setOpaque(true);
 
         JLabel label;
         label = createUpdateButton(Calendar.YEAR, -1);
         label.setText("<<");
         //label.setToolTipText(resource.getString("datecombobox.prevyear"));
		 label.setToolTipText("previous year");
 
         header.add(Box.createHorizontalStrut(12));
         header.add(label);
         header.add(Box.createHorizontalStrut(12));
 
         label = createUpdateButton(Calendar.MONTH, -1);
         label.setText("<");
         //label.setToolTipText(resource.getString("datecombobox.prevmonth"));
		 label.setToolTipText("previous month");
        header.add(label);
 
         monthLabel = new JLabel("", JLabel.CENTER);
         monthLabel.setForeground(foreground);
         header.add(Box.createHorizontalGlue());
        header.add(monthLabel);
         header.add(Box.createHorizontalGlue());
 
         label = createUpdateButton(Calendar.MONTH, 1);
         label.setText(">");
        //label.setToolTipText(resource.getString("datecombobox.nextmonth"));
		label.setToolTipText("next month");
        
         header.add(label);

         label = createUpdateButton(Calendar.YEAR, 1);
         label.setText(">>");
        // label.setToolTipText(resource.getString("datecombobox.nextyear"));
		label.setToolTipText("next year");

         header.add(Box.createHorizontalStrut(12));
         header.add(label);
         header.add(Box.createHorizontalStrut(12));
 
         popup = new JPopupMenu();
         popup.setBorder(BorderFactory.createLineBorder(Color.black));
         popup.setLayout(new BorderLayout());
         popup.setBackground(background);
         popup.addPopupMenuListener(this);
         popup.add(BorderLayout.NORTH, header);
     }
 
     // update the Popup when either the month or the year of the calendar has been changed
 protected void updatePopup() {
         monthLabel.setText( monthFormat.format(calendar.getTime()) );
         if (days != null) {
         popup.remove(days);
         }
         days = new JPanel(new GridLayout(0, 7));
         days.setBackground(background);
         days.setOpaque(true);
 
         Calendar setupCalendar = (Calendar) calendar.clone();
         setupCalendar.set(Calendar.DAY_OF_WEEK, setupCalendar.getFirstDayOfWeek());
         for (int i = 0; i < 7; i++) {
         int dayInt = setupCalendar.get(Calendar.DAY_OF_WEEK);
         JLabel label = new JLabel();
         label.setHorizontalAlignment(JLabel.CENTER);
         label.setForeground(foreground);
         if (dayInt == Calendar.SUNDAY) {
             label.setText("SUN");
         } else if (dayInt == Calendar.MONDAY) {
             label.setText("MON");
         } else if (dayInt == Calendar.TUESDAY) {
             label.setText("TUE");
         } else if (dayInt == Calendar.WEDNESDAY) {
             label.setText("WED");
         } else if (dayInt == Calendar.THURSDAY) {
             label.setText("THU");
         } else if (dayInt == Calendar.FRIDAY) {
             label.setText("FRI");
         } else if (dayInt == Calendar.SATURDAY){
             label.setText("SAT");
         }
         days.add(label);
        setupCalendar.roll(Calendar.DAY_OF_WEEK, true);
         }
 
         setupCalendar = (Calendar) calendar.clone();
         setupCalendar.set(Calendar.DAY_OF_MONTH, 1);
         int first = setupCalendar.get(Calendar.DAY_OF_WEEK);
         for (int i = 0; i < (first - 1); i++) {
         days.add(new JLabel("")); 
         }
         for (int i = 1; i <= setupCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++) { 
        final int day = i;
         final JLabel label = new JLabel(String.valueOf(day));
         label.setHorizontalAlignment(JLabel.CENTER);
         label.setForeground(foreground);
         label.addMouseListener(new MouseListener() {
             public void mousePressed(MouseEvent e) {}
            public void mouseClicked(MouseEvent e) {}
             public void mouseReleased(MouseEvent e) {
                 label.setOpaque(false);
                label.setBackground(background);
                 label.setForeground(foreground);
                 calendar.set(Calendar.DAY_OF_MONTH, day);
                 comboBox.setSelectedItem(dateFormat.format(calendar.getTime()));
                 // hide();
 // hide is called with setSelectedItem() ... removeAll()
 comboBox.requestFocus();
             }
             public void mouseEntered(MouseEvent e) {
                 label.setOpaque(true);
                 label.setBackground(selectedBackground);
                 label.setForeground(selectedForeground);
             }
             public void mouseExited(MouseEvent e) {
                 label.setOpaque(false);
                 label.setBackground(background);
                 label.setForeground(foreground);
             }
             });
 
         days.add(label);
         }
         
         popup.add(BorderLayout.CENTER, days);
         popup.pack(); 
     }
     }
 
 }
 
Das Problem ist das Swing mit AWT vermischt wird.
Mach aus deiner TextArea einfach eine JTextArea und dann sollte es passen.
Möglichst auch die anderen Komponenten auf Swing umstellen.
 
Das werde ich gerne versuchen.
Vielen vielen Dank für deine schnellen Antworten.

Mahlzeit😀

Mfg.
J. Balsiger
 
Kann ich nur Beipflichten.
Da bestätigt sich wieder, wer sein Problem vernünftig beschreiben kann kriegt schneller geholfen 🙂
 
Super, danke es hat geklappt und definitiv an der Vermischung der AWT/Swing komponenten gelegen.

Mfg.
J. Balsiger
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben