Java GUI Meilleur moyen de créer une table de JTables?


[MISE À JOUR!!!!] C'est le produit fini:

: )

entrez la description de l'image icientrez la description de l'image ici Je travaille donc sur un programme qui m'aide à organiser et imprimer des sièges pour le dîner. J'ai une classe student avec des variables d'instance de leur prénom,nom, etc. J'ai aussi une classe DinnerTable qui a la liste de Student et String teacherName. J'ai créé une interface graphique qui facilite l'attribution de différents sièges. J'ai déjà un onglet sur JTabbedPane qui organise l'étudiant informations (si elles sont disponibles ou non) et randomise les tables qu'ils siègent. Maintenant, pour mieux visualiser les tableaux et pour faciliter l'affectation de chaque élève à un siège spécifique, je dois faire quelque chose comme ceci: entrez la description de l'image ici Je veux utiliser les objets DinnerTable réels dans le TableModel de sorte que chaque fois que je modifie quelque chose sur ce cadre, les modifications sont traduites dans les objets. Cependant, je ne suis pas vraiment sûr de savoir quoi faire. Dois-je:

1.Créer des tables(une table JTable pour chaque DinnerTable) imbriqué dans les cellules d'un plus grand JTable? Mais comment puis-je effectuer des actions telles que glisser les étudiants entre la table à manger? Ou 2.Aligner JTables dans GridLayout ou GridBagLayout? Mais encore une fois, comment puis-je échanger des étudiants?

Merci! paquet DinnerList;

  public class Student 
  {
  private String lastName;
  private String firstName;
  private int grade;
  private int table;
  private boolean gender;//Male=true, female=false;
  private boolean available; //true=available;

public Student()
{
    lastName="";
    firstName="";
    grade=0;
    table=0;
    gender=true;
    available=true;
}
public Student(String l, String f, int i, boolean g, boolean a)
{

    lastName=l;
    firstName=f;
    grade=i;
    gender=g;
    available=a;
    //table is not written back to the txt.
    table=0;
}
//Getters

  public String getLastName()
   {
    return lastName;
  }
  public String getFirstName()
{
    return firstName;
}
public int getGrade()
{
    return grade;
}       
public int getTable()
{
    return table;
}
  public boolean getGender()
{
    return gender;
}
public boolean getAvailable()
{
    return available;
}

//Setters
public void setLastName(String s)
{
    this.lastName=s;
}
public void setFirstName(String s)
{
    firstName=s;
}
public void setGrade(int i)

{
    grade=i;
}
public void setTable(int hiahia)
{
    table=hiahia;
}
public void setGender(boolean b)
{
    gender=b;
}
public void setAvailable(boolean b)
{
    available=b;
}

//Miscellaneous
  public String toString()
  {
    String a="";

     a=lastName+","+firstName+","+Integer.toString(grade)+","+Boolean.toString(gender)+","+Boolean.toString(available);
    return a;
    }
 }

///////////////////////////////////

 package DinnerList;

   import java.util.ArrayList;
   import java.util.List;

  public class DinnerTable 
{
    private List<Student> members= new ArrayList<Student>();
    private int tableNumber=0;
    private int capacity=0;
    private String teacherName="";
    private boolean available=true;

public DinnerTable(int a, int b, String c, boolean d)
{
    tableNumber=a;
    capacity=b;
    teacherName=c;
    available=d;
}

public void setTableNumber(int a) {tableNumber=a;}
public void setCapacity(int a) {capacity=a;}
public void setTeacherName(String a) {teacherName=a;}
public void setAvailable(boolean b) {available=b;}
public void add(Student s)
{
    if(available&&(members.size()<capacity))
    { this.members.add(s); }
    else if(!available)
    { System.out.println("Adding Student failed, table "+tableNumber+" not available");}
    else
    { System.out.println("Adding Student failed, table "+tableNumber+" is full");}
}

public int getTableNumber() 
{return tableNumber;}
public int getCapacity() {return this.capacity;}
public String getTeacherName() {return teacherName;}
public boolean getAvailable() {return available;}
public List<Student> getMembers(){return members;}
public void remove(Student s) 
{
    if(members.contains(s))
    {
        members.remove(s);
    }
    else
    {
        System.out.println("Failed to remove student from table because it wasn't there");
    }
  }
}

/////////////////////

package DinnerList;

import java.awt.Component;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

public class DinnerTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
          boolean hasFocus, int row, int column)
{
    Object huahua =table.getModel().getValueAt(row, column);
    String ppp="";
    if(huahua!=null)
    {
        if(huahua instanceof Student)
        {
            ppp=((Student) huahua).getLastName()+", "+((Student)huahua).getFirstName();
        }
        else if(huahua instanceof String)
        {
            ppp=(String)huahua;
        }
        else
        {
            System.out.println("Error: DinnerTableCellRenderer intakes unknown data type");
        }
    }
    else
    {
        ppp="";
    }
    JLabel label = (JLabel)super.getTableCellRendererComponent(table, ppp,isSelected, hasFocus,row, column);
    return label;
    }

}

//////////

package DinnerList;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

public class DinnerTableModel extends AbstractTableModel implements TableModel
 {
    private final String[] columnNames={"","","",""};
    private List<DinnerTable> tableCollection= new ArrayList<DinnerTable>();


public DinnerTableModel(List<DinnerTable> huhu)
{
    tableCollection.addAll(huhu);
}
public int getColumnCount() 
{
    return columnNames.length;
}

public int getRowCount() 
{
        if(tableCollection.size()%4==0)
        {
            return tableCollection.size()/4;
        }
        else
        {
            return (int)(tableCollection.size()/4)+1;
        }
}

public String getColumnName(int col) 
{
    return columnNames[col];
}

public DinnerTable getTableAt(int row, int column)
{
        if(tableCollection.size()>=(Integer)((row)/8)+column+1)
        {
            return tableCollection.get((Integer)((row)/8)+column);
        }
        else
        {
            return null;
        }

}
public Object getValueAt(int rowIndex, int colIndex) 
{
    DinnerTable dd= this.getTableAt(rowIndex, colIndex);
    String ss= "";
    if(dd==null)
    {
            return "";
    }
    else if(rowIndex%8==0)
    {
            return (dd.getTableNumber()+". "+dd.getTeacherName());
    }
    else if(dd.getMembers().size()>=rowIndex%8)
    {
            return dd.getMembers().get(rowIndex%8);
    }
    else
    {
            return "";
    }
}


public Class getColumnClass(int c) 
{
    return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col) 
{
        if(this.getValueAt(row, col) instanceof Student)
        {
            return true;
        }
        else
        {
            return false;
        }
}
    public void setValueAt(Object aValue, int rowIndex, int columnIndex)
    {

  if(aValue instanceof Student)
  {
        if(rowIndex%8!=0)
        {
            if(null!=this.getTableAt(rowIndex,columnIndex))
            {
                this.getTableAt(rowIndex,columnIndex).getMembers().set(rowIndex%8-1, (Student)aValue);
            }
            else
            {
                System.out.println("error: Attempting to put student in nonexistent table in table list gui");
            }
        }
        else
        {
            System.out.println("error: Attempting to put student in a string in table list gui");
        }
  }
  else if(aValue instanceof String)
  {
        System.out.println("error: Attempting to change teacher name in tablelist gui");
  }
  else
  {
        System.out.println("error: Attempting to set unknown object type in tablelist gui");
  }
}

}

////****************////

JTable tableTable= new JTable(new DinnerTableModel(tables));
for(int hihihi=0;hihihi<tableTable.getColumnCount();hihihi++)
{
  tableTable.getColumnModel().getColumn(hihihi).setCellRenderer(new   DinnerTableCellRenderer());
}
JScrollPane scrollpaneB1= new JScrollPane();
scrollpaneB1.add(tableTable);
panelB.add(scrollpaneB1);
Author: Ptolemorphism, 2017-09-21

1 answers

Je suis nouveau dans la programmation et j'ai beaucoup de questions. C'est très gentil de votre part d'être si patient! : ) Cependant, j'ai un autre JTable qui intègre une autre classe TableModel. J'ai exécuté des tests et il semble que le modèle change chaque fois que les objets d'origine changent, même si je n'ai utilisé aucun propertychangelisteners. C'est très confus pour moi...

JTable est l'un des composants les plus complexes de l'API (JTree et les composants de texte ont été les suivants), si vous le pouvez devenez à l'aise avec elle, vous serez un long chemin pour devenir à l'aise avec l'API globale.

Il existe de nombreuses façons de notifier au TableModel qu'un objet a changé, mais l'une des meilleures façons est de le faire de manière découplée, vous n'avez donc pas besoin de maintenir une référence au TableModel chaque fois que l'objet Student peut changer.

Cela suggère que l'objet Student lui-même devrait générer une sorte d'événement de changement, que les parties intéressées (comme le TabelModel) peuvent écoutez et prenez des mesures quand elles se produisent.

De cette façon, vous pouvez changer l'objet Student n'importe où dans votre code sans vous soucier de qui pourrait avoir besoin de savoir que l'objet a changé.

Maintenant, cela se résume essentiellement à un modèle d'observateur, Swing implémente ce type de fonctionnalité dans ses écouteurs, ChangeListener vient à l'esprit comme un candidat possible, mais PropertyChangeListener est une option plus puissante, car elle génère des événements basés sur la propriété qui a changé.

Dans certains cas, vous ne vous soucierez probablement pas de la propriété qui a changé, mais dans le cas de TableModel, c'est très utile.

Ceci est une simple démonstration du concept, en utilisant deux tableaux. Vous pouvez modifier n'importe quelle valeur dans l'une ou l'autre table et la table adverse sera mise à jour lorsque la valeur est validée. Maintenant, vous pouvez également modifier l'instance de Student dans votre code et vous obtiendrez le même résultat, mais c'était un simple exemple pour créer.

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Student student = new Student("Skywalker", "Luke", 0, true, true);
                StudentTabelModel leftModel = new StudentTabelModel(student);
                StudentTabelModel rightModel = new StudentTabelModel(student);

                JTable leftTable = new JTable(leftModel);
                leftTable.setGridColor(Color.GRAY);
                JTable rightTable = new JTable(rightModel);
                rightTable.setGridColor(Color.GRAY);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridLayout(0, 2));
                frame.add(new JScrollPane(leftTable));
                frame.add(new JScrollPane(rightTable));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class StudentTabelModel extends AbstractTableModel {

        private List<Student> students = new ArrayList<>(25);
        private PropertyChangeListener propertyChangeListener;

        public StudentTabelModel(Student... students) {
            propertyChangeListener = new StudentPropertyChangeListener();
            add(students);
        }

        public void add(Student... students) {
            if (students != null && students.length > 0) {
                int startRow = this.students.size();
                for (Student student : students) {
                    student.addPropertyChangeListener(propertyChangeListener);
                    this.students.add(student);
                }
                fireTableRowsInserted(startRow, this.students.size() - 1);
            }
        }

        public void remove(Student ...students) {
            if (students != null && students.length > 0) {
                for (Student student : students) {
                    int index = this.students.indexOf(student);
                    if (index != -1) {
                        student.removePropertyChangeListener(propertyChangeListener);
                        this.students.remove(student);
                        fireTableRowsDeleted(index, index);
                    }
                }
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

        @Override
        public int getRowCount() {
            return students.size();
        }

        @Override
        public int getColumnCount() {
            return 6;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
                case 0:
                case 1:
                    return String.class;
                case 2:
                case 3:
                    return Integer.class;
                case 4:
                case 5:
                    return Boolean.class;
            }
            return Object.class;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Student student = students.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    return student.getLastName();
                case 1:
                    return student.getFirstName();
                case 2:
                    return student.getGrade();
                case 3:
                    return student.getTable();
                case 4:
                    return student.getGender();
                case 5:
                    return student.getAvailable();
            }
            return "??";
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            Student student = students.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    student.setLastName(aValue == null ? null : aValue.toString());
                    break;
                case 1:
                    student.setFirstName(aValue == null ? null : aValue.toString());
                    break;
                case 2:
                    if (aValue instanceof Integer) {
                        student.setGrade((Integer) aValue);
                    }
                    break;
                case 3:
                    if (aValue instanceof Integer) {
                        student.setTable((Integer) aValue);
                    }
                    break;
                case 4:
                    if (aValue instanceof Boolean) {
                        student.setGender((Boolean) aValue);
                    }
                    break;
                case 5:
                    if (aValue instanceof Boolean) {
                        student.setAvailable((Boolean) aValue);
                    }
                    break;
            }
        }

        protected class StudentPropertyChangeListener implements PropertyChangeListener {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getSource() instanceof Student) {
                    Student student = (Student) evt.getSource();
                    int row = students.indexOf(student);
                    if (row != -1) {
                        switch (evt.getPropertyName()) {
                            case "lastName":
                                fireTableCellUpdated(row, 0);
                                break;
                            case "firstName":
                                fireTableCellUpdated(row, 1);
                                break;
                            case "grade":
                                fireTableCellUpdated(row, 2);
                                break;
                            case "table":
                                fireTableCellUpdated(row, 3);
                                break;
                            case "gender":
                                fireTableCellUpdated(row, 4);
                                break;
                            case "avaliable":
                                fireTableCellUpdated(row, 5);
                                break;
                        }
                    }
                }
            }

        }

    }

    public class Student {

        private String lastName;
        private String firstName;
        private int grade;
        private int table;
        private boolean gender;//Male=true, female=false;
        private boolean available; //true=available;

        private PropertyChangeSupport propertyChangeSupport;

        public Student() {
            this("", "", 0, false, true);
        }

        public Student(String l, String f, int i, boolean g, boolean a) {

            lastName = l;
            firstName = f;
            grade = i;
            gender = g;
            available = a;
            //table is not written back to the txt.
            table = 0;
            propertyChangeSupport = new PropertyChangeSupport(this);
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }
//Getters

        public String getLastName() {
            return lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public int getGrade() {
            return grade;
        }

        public int getTable() {
            return table;
        }

        public boolean getGender() {
            return gender;
        }

        public boolean getAvailable() {
            return available;
        }

//Setters
        public void setLastName(String s) {
            String old = lastName;
            this.lastName = s;
            propertyChangeSupport.firePropertyChange("lastName", old, lastName);
        }

        public void setFirstName(String s) {
            String old = firstName;
            firstName = s;
            propertyChangeSupport.firePropertyChange("firstName", old, firstName);
        }

        public void setGrade(int i) {
            int old = grade;
            grade = i;
            propertyChangeSupport.firePropertyChange("grade", old, grade);
        }

        public void setTable(int hiahia) {
            int old = table;
            table = hiahia;
            propertyChangeSupport.firePropertyChange("table", old, table);
        }

        public void setGender(boolean b) {
            boolean old = gender;
            gender = b;
            propertyChangeSupport.firePropertyChange("gender", old, gender);
        }

        public void setAvailable(boolean b) {
            boolean old = available;
            available = b;
            propertyChangeSupport.firePropertyChange("available", old, available);
        }

//Miscellaneous
        @Override
        public String toString() {
            String a = "";

            a = lastName + "," + firstName + "," + Integer.toString(grade) + "," + Boolean.toString(gender) + "," + Boolean.toString(available);
            return a;
        }
    }
}

Rappelez-vous, cela repose sur l'INSTANCE du Student été partagé, si vous créez deux instances différentes de l'objet Student et que vous vous attendez à ce que les modifications d'une instance soient reflétées dans l'autre, vous serez déçu

 1
Author: MadProgrammer, 2017-09-23 22:40:17