In einem Raster auswählen

AndiE

Top Contributor
Ich habe da für ein privates Projekt die Überlegung, wie man die GUI eines Anwesenheitsnachweises am nutzerfreundlichsten gestalten würde. Mir schwebt dabei ein Raster vor, an dessen linker Seite sich die Namen der Mitglieder befinden und oben als Spaltenmarkierungen die Tageszahlen. Die Zahlen und Namen bilden ein Raster, und in die dabei entstehenden Kästchen kann man dann den Status wie "K-Krank" oder "U-Urlaub" eintragen.

Datentechnisch ist das recht einfach handhabbar, wenn man z.B. eine Klasse "Club" mit einer "List of Customers" hat. Zusätzlch ist da ein String "month" enthalten.
Dann sind der in Classe "Customer" die "List of PresenceDays" enthalten und ein String "Name". In der Klasse "PresenceDay" wäre dann ein Strinf "status" und ein Date-Objekt enthalten.

Man kann nun einfach über die Listen interieren und eine Matrix erzeugen. Soweit ist mir das klar.

Die Frage ist nun, wie man das editiert. Am einfachsten wäre es auf ein Kästchen zu klicken und dann ein Auswahlfeld(Listbox) zu bekommen. Mit dem Druck auf den "OK"-Button wird der Eintrag geändert.
Und da ist die Frage, wie ich weiß, auf welches Lästchen der Nutzer geklickt hat.

Wie kann ich die x,y-Informationen, die ich bei "OnMouseClicked", erhalte so umrechnen, dass ich auf das richtige Kästchen komme.

Hat da jemand eine Idee?
 
Du kennst doch die Koordinaten der Kästchen. Im besten Fall sind die Kästchen, in die Du etwas eintragen möchtest (also, die die rechts vom Namen stehen) gleich breit und gleich hoch, dann kannst Du die Indizes unmittelbar berechnen. Im schlimmsten Fall musst Du halt iterieren.

In Swing könnte ich da schnell ein Beispiel erstellen, wenn es sein muss.
 
Du kannst bei Swing in der JTable einen TableCellRenderer und einen TableCellEditor definieren und verwenden wenn ich mich richtig erinnere. Damit kannst du beliebige Komponenten als Zelleninhalt verwenden. Allerdings ist die Anzeige einer "Personal/Kalender"-Kombination so etwas unhandlich, weil du viele Spalten brauchst, fuer jeden Tag eine.

Einfacher wird es sein wenn du dir eine eigene Komponente schreibst welche auf der linken Seite die Namen des Personals hat, und auf der rechten Seite einen "Zeitstrahl" auf dem man horizontal vor und zurueck scrollen kann. Das ist Aufwand allerdings. Ha, das heiszt "Gantt Chart" was du dafuer suchst, der auch direkt editierbar sein soll. Eventuell gibt es da schon eine Komponente welche fertig ist und du verwenden kannst.
 
Was gemaltes.

Das habe ich auch schon überlegt. Ich denke, was gemaltes ist eher sinnvoll, da es hat ja nur das Aussehen einer Tabelle hat. Es werden ja keine Datensätze in dem Sinne abgebildet, und es sind ziemlich viele Lücken. Bei einer Tabelle ist das ja eher voll ausgefüllt.
Ich glaube aber, dass sich das vom Programmieraufwand beides nichts nimmt, oder?
 
Java:
package presence;

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Grid extends JPanel {
   
    public  Grid() {
        setPreferredSize( new Dimension( 1000,600));
    }
   
    protected void paintComponent(Graphics g) {
        int COUNT=20;
        int HEIGHT=25;
        int NAMESPACE=200;
        int DAYSOFMONTH=31;
       
        super.paintComponent(g);
       
        int i;
        int j;
        int xPos;
        int yPos;
       
       
       
        for(j=0;j<DAYSOFMONTH;j++) {
            xPos=NAMESPACE+HEIGHT*j;
            g.drawRect(xPos,0,HEIGHT,HEIGHT);
            g.drawString(Integer.toString(j+1),xPos,HEIGHT);
           
        }
        for(i=0;i<COUNT;i++) {
            g.drawRect(0,(i+1)*HEIGHT,HEIGHT,HEIGHT);
            g.drawString(Integer.toString(i+1),0,(i+2)*HEIGHT);
            g.drawRect(0,(i+1)*HEIGHT,NAMESPACE,HEIGHT);
            for(j=0;j<DAYSOFMONTH;j++) {
                xPos=NAMESPACE+j*HEIGHT;
                yPos=(i+1)*HEIGHT;
                g.drawRect(xPos,yPos,HEIGHT,HEIGHT);
                g.drawString("A",xPos+2,yPos+HEIGHT-2);
               
            }
        }
               
    }

}

Java:
package presence;

   
 
public class PresenceGrid {
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
   
    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        GridView gv= new GridView();
        gv.start();
    }
   
    /*
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
     */
}

Java:
package presence;

import javax.swing.JFrame;

public class GridView {

   
       
        private void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("HelloWorldSwing");
           
           
   
            Grid g= new Grid();
           
         
              frame.setContentPane(g);
            //Display the window.
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
   
        public void start(){
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
   
}

Soweit habe ich das jetzt und er zeigt mir das an, was er soll.
 

Anhänge

  • Bildschirmfoto_2025-01-08_14-34-15.png
    Bildschirmfoto_2025-01-08_14-34-15.png
    8,6 KB · Aufrufe: 0
Ja, und genauso kannst Du ja zurückrechnen, z. B. in Grid zwei Methoden:
Java:
public int getRowAt(int y) {
    int row = (y - HEIGHT) / HEIGHT;
    return row >= 0 && row < COUNT ? row : -1;
}
public int getDayOfMonthAt(int x) {
    int day = (x - NAMESPACE) / HEIGHT;
    return day >= 0 && day < DAYSOFMONTH ? day + 1 : -1;
}
Bei Klicks außerhalb des Bereichs würden die Methoden -1 liefern. Achtung: getDayOfMonth liefert Werte zwischen 1 und DAYSOFMONTH (incl.), ist also nicht 0-basiert. Für 0-basierte Werte statt day + 1 einfach day zurückgeben.

Und dann z. B. mit einem MouseListener auf dem Grid-Objekt:
Java:
grid.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        Point p = e.getPoint();
        int row = grid.getRowAt(e.y);
        int day = grid.getDayOfMonth(e.x);
        // mach was mit row and day
    }
});
 

Neue Themen


Zurück
Oben