JavaFX: Nested Tables - java

It is possible to create a table that contains other subtables in javafx like in the picture?
The program in the photo is written in javafx only that it is closed source.
Is there any other external or internal component in java that allows me to create a similar interface?
My problem is the same as this: JavaFX TableView: open detail information between rows on click
However, i need to load different value in the sub tables for every row. How can i do this?
This is the creation of my sub-tabs.
private Node createDetailsPane(ObjectProperty<Model> item) {
VBox vBox = new VBox();
ObservableList<Model> dv = FXCollections.observableArrayList();
ObservableList<Model> dl = FXCollections.observableArrayList();
ObservableList<Model> dp = FXCollections.observableArrayList();
TableView visite = new TableView();
TableView latte = new TableView();
TableView parti = new TableView();
visite.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
latte.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
parti.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
visite.setTableMenuButtonVisible(true);
latte.setTableMenuButtonVisible(true);
parti.setTableMenuButtonVisible(true);
visite.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
latte.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
parti.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
visite.getColumns().addAll(idVisita, dataVisita, azioniTerapeutiche, descrizioneVisita, incinta, dataPrevistaParto, veterinario);
latte.getColumns().addAll(idLatte, litri, dataProduzione);
parti.getColumns().addAll(idParto, dataParto, azioniParticolari);
visite.setFixedCellSize(25);
visite.prefHeightProperty().bind(visite.fixedCellSizeProperty().multiply(Bindings.size(visite.getItems()).add(2)));
visite.minHeightProperty().bind(visite.prefHeightProperty());
visite.maxHeightProperty().bind(visite.prefHeightProperty());
latte.setFixedCellSize(25);
latte.prefHeightProperty().bind(latte.fixedCellSizeProperty().multiply(Bindings.size(latte.getItems()).add(2)));
latte.minHeightProperty().bind(latte.prefHeightProperty());
latte.maxHeightProperty().bind(latte.prefHeightProperty());
parti.setFixedCellSize(25);
parti.prefHeightProperty().bind(parti.fixedCellSizeProperty().multiply(Bindings.size(parti.getItems()).add(2)));
parti.minHeightProperty().bind(parti.prefHeightProperty());
parti.maxHeightProperty().bind(parti.prefHeightProperty());
parti.setItems(dp);
latte.setItems(dl);
String id;
if(treeView.getSelectionModel().getSelectedIndices().get(treeView.getSelectionModel().getSelectedItems().size()-1) != -1) {
id = treeView.getSelectionModel().getSelectedItems().get(treeView.getSelectionModel().getSelectedItems().size()-1).getIdProv();
try {
Connection conn = Driver.connection();
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/animali?autoReconnect=true&useSSL=false", "admin", "admincs97");
Statement stmt = conn.createStatement();
sql = "SELECT DISTINCT `ID_VISITA`,`DATA_VISITA`,`AZIONI_TERAPEUTICHE`,`DESCRIZIONE_VISITA`,`STATO_VISITA`,`GRAVIDA_DA_GG`,`DATA_PREVISTA_PARTO`,`VETERINARIO` FROM `visite` "
+ "LEFT JOIN `anagrafe` USING(`ID_PROVVISORIO`, `BOLO`) "
+ "LEFT JOIN `parti` USING(`ID_PROVVISORIO`, `BOLO`) "
+ "LEFT JOIN `latte` USING(`ID_PROVVISORIO`, `BOLO`) "
+where;
String temp = "";
if(where.trim().length() > 0)
temp += " AND visite.`ID_PROVVISORIO` = '"+id+"'";
else
temp = "WHERE visite.`ID_PROVVISORIO` = '"+id+"'";
sql += temp;
ResultSet rs = stmt.executeQuery(sql);
if(rs.next())
do {
dv.add(new Model( rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7), rs.getString(8)));
/*rs.getString(13), rs.getString(14), rs.getString(15), rs.getString(16), rs.getString(17), rs.getString(18),
rs.getString(19), rs.getString(20), rs.getString(21), rs.getString(22), rs.getString(23), rs.getString(24),
rs.getString(25), rs.getString(26) */
} while(rs.next());
} catch(SQLException e) {
new FxDialogs().showException("Errore", "Errore nel caricamento dei dati", e);
}
}
visite.setItems(dv);
vBox.getChildren().addAll(visite, latte, parti);
return vBox ;
}
Everything works until I select multiple rows in the main table.
If for example I have two main lines, if I select first the second and then the first the subtables give me back the same value.

Related

how do i update my jtable after i add or delete my item

Im currently developing a database project. my jtextfield, addbutton, editbutton and the jtable was originally on one jframe. but when i made a addbutton to open another jframe and place the items to be added there, it works but it does not update my jtable, my jtable only updates after i make another action like editing or adding another item, what should be the problem here? here are the example of my edit button. btw i need it to be inserted and updated into my mysql
if(editID.getText() != null)
{
String UpdateQuery = null;
PreparedStatement ps = null;
Connection con = main.getConnection();
try{
UpdateQuery = "UPDATE mydatabase SET name = ?, price = ?"
+ ", quantity = ? WHERE id = ?";
ps = con.prepareStatement(UpdateQuery);
ps.setString(1, editName.getText());
ps.setString(2, editPrice.getText());
ps.setString(3, editQuantity.getText());
ps.setString(4, editID.getText());
ps.executeUpdate();
main.getProductList();
main.Show_Products_In_JTable();
JOptionPane.showMessageDialog(null, "Product Updated");
}catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}else{
JOptionPane.showMessageDialog(null, "One Or More Fields Are Empty Or Wrong");
}
so here is the two methods that i used to edit the table... but it seems incomplete, like i need a method in the main to simultaneously refresh my jtable. my brain are really exploding right now with this problem. cause i cant see any problem why moving my edit method from another jframe could affect my program.
public ArrayList<Database1> getProductList()
{
ArrayList<Database1> productList = new ArrayList<Database1>();
Connection con = getConnection();
String query = "SELECT * FROM mydatabase";
Statement st;
ResultSet rs;
try {
st = con.createStatement();
rs = st.executeQuery(query);
Database1 mydatabase;
while(rs.next())
{
mydatabase = new Database1(rs.getString("id"),rs.getString("name"),rs.getInt("price"),rs.getInt("quantity"));
productList.add(mydatabase);
}
} catch (SQLException ex) {
Logger.getLogger(mainWindow.class.getName()).log(Level.SEVERE, null, ex);
}
return productList;
}
public void Show_Products_In_JTable()
{
ArrayList<Database1> list = getProductList();
DefaultTableModel model = (DefaultTableModel)itemTable.getModel();
model.setRowCount(0);
Object[] row = new Object[4];
for(int i = 0; i < list.size(); i++)
{
row[0] = list.get(i).getId();
row[1] = list.get(i).getName();
row[2] = list.get(i).getQuantity();
row[3] = list.get(i).getPrice();
model.addRow(row);
}
itemTable.setModel(model);
model.fireTableDataChanged();
}

Not getting total records from the database

I have 4 records in my database table, but i am getting only one record from the function. please check my code once. When i call the getMaterialTransferRecords() function inside this function i have another function getMaterialUnit(). I am not able to find the solution. Please any one help me.
This is the query i am executing in my sqlyog. please check it once
Above is my query and below is the result.
This is how i am calling the function.
// Fetch Data from User Table
int startPageIndex = Integer.parseInt(request.getParameter("jtStartIndex"));
int recordsPerPage = Integer.parseInt(request.getParameter("jtPageSize"));
String jtSorting = request.getParameter("jtSorting");
MaterialTransferUtils utils = new MaterialTransferUtils();
//System.out.println("Cash Purchases Start Page Index:"+startPageIndex+" recordsPerPage:"+recordsPerPage);
if(jtSorting != null)
{
jtSorting = jtSorting.replaceAll("material_destn_code", "material_destn_code");
jtSorting = jtSorting.replaceAll("date", "transferred_on");
}
// Fetch Data from Cash Memo Table
mtList = utils.getMaterialTransferRecords(startPageIndex, recordsPerPage,jtSorting);
Please check the code once.
public List<MaterialTransferBean> getMaterialTransferRecords(int startPageIndex, int recordsPerPage,String jtSorting)
{
List<MaterialTransferBean> list = new ArrayList<MaterialTransferBean>();
con=com.s2s.bssb.database.ConnectionFactory.getConnection();
MaterialTransferBean mtbean = null;
String sortStr = "material_destn_code DESC";
if(null != jtSorting)
sortStr = jtSorting;
String query = "SELECT sno,material_loc_code,transferred_on,mr_no,do_no,material_destn_code,material_id,quantity,unit_price, "
+ "gst,remarks FROM material_transfer ORDER BY "+sortStr+" LIMIT "+recordsPerPage+" offset "+startPageIndex+"";
System.out.println(query);
if(con!=null){
try{
ps=con.prepareStatement(query);
rs=ps.executeQuery();
while(rs.next()){
MaterialTransferBean bean = new MaterialTransferBean();
bean.setSno(rs.getInt("sno"));
bean.setMaterial_loc_code(rs.getString("material_loc_code"));
bean.setDate(rs.getDate("transferred_on"));
bean.setMr_no(rs.getString("mr_no"));
bean.setDo_no(rs.getString("do_no"));
bean.setMaterial_destn_code(rs.getString("material_destn_code"));
bean.setQuantity(rs.getDouble("quantity"));
bean.setUnit_price(rs.getDouble("unit_price"));
bean.setAmount(rs.getDouble("quantity")*rs.getDouble("unit_price"));
bean.setGst(((rs.getDouble("quantity")*rs.getDouble("unit_price"))*(rs.getDouble("gst")))/100);
bean.setTtl_amount((rs.getDouble("quantity")*rs.getDouble("unit_price"))+(((rs.getDouble("quantity")*rs.getDouble("unit_price"))*(rs.getDouble("gst")))/100));
bean.setRemarks(rs.getString("remarks"));
mtbean = new MaterialTransferBean();
mtbean = getMaterialUnit(rs.getInt("material_id"));
bean.setMaterial(mtbean.getMaterial());
bean.setUnit(mtbean.getUnit());
list.add(bean);
}
rs.close();
com.s2s.bssb.database.ConnectionDB.close(con);
com.s2s.bssb.database.ConnectionDB.close(ps, con);
}catch(SQLException sql_ex){
sql_ex.printStackTrace();
}
}else{
System.out.println("Connection Not Created");
}
return list;
}
public MaterialTransferBean getMaterialUnit(int material_id){
MaterialTransferBean bean = null;
con=com.s2s.bssb.database.ConnectionFactory.getConnection();
String query = "select material,unit from materials where id=?";
if(con!=null){
try{
ps=con.prepareStatement(query);
ps.setInt(1, material_id);
rs=ps.executeQuery();
while(rs.next()){
bean = new MaterialTransferBean();
bean.setMaterial(rs.getString("material"));
bean.setUnit(rs.getString("unit"));
}
}catch(SQLException sql_ex){
sql_ex.printStackTrace();
}
}
return bean;
}

Fetching multiple joins data in Set

I am trying to fetching album details and all images associated with that album to Set piSet but it is not fetching all images to set piSet
I want like
albumname in al object
ABC
images in piSet
image1
image2
image3
....
Data fetching code is
con = ConnectionFactory.getConnection();
List<Album> aList = new ArrayList<Album>();
try {
ps = con.prepareStatement("select distinct album.*,pi.* from "
+ "atom as a "
+ "left join album as album "
+ "on "
+ "a.id=album.aid "
+ "left join post_images as pi "
+ "on "
+ "album.id=pi.album_id "
+ "where "
+ "a.id=? "
+ "and a.status=? ");
ps.setLong(1, aid);
ps.setString(2, "Active");
rs = ps.executeQuery();
while (rs.next()) {
Set<PostImages> piSet = new HashSet<PostImages>();
Album al = new Album();
al.setId(rs.getLong("album.id"));
al.setName(rs.getString("album.name"));
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
piSet.add(pi);
al.setPostImageses(piSet);
aList.add(al);
}
} catch (SQLException e) {}
How to modify above code to fetch all images to 'PiSet'.
Assume id is unique in album table, above code can satisfy your requirement:
rs = ps.executeQuery();
HashMap<Long, Album> AlbumMap = new HashMap<Long, Album>();
while (rs.next()) {
Long albumId = rs.getLong("album.id");//assume album.id is unique.
Album al = AlbumMap.get(albumId);
if (al == null) {
al = new Album();
al.setId(albumId);
al.setName(rs.getString("album.name"));
Set<PostImages> piSet = new HashSet<PostImages>();
al.setPostImageses(piSet);
aList.add(al);
AlbumMap.put(albumId, al);
}
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
al.getPostImageses().add(pi);
}
You need to keep a map from id to Album instances, and only create a new Album when there is no instance yet for the given id.
I'd also advise you to let Album handle the Set internally, and just add images to album, instead of setting the set to album.
Map<Long, Album> albumMap = new HashMapMap<>();
while (rs.next()) {
long albumId = rs.getLong("album.id");
Album album = albumMap.get(albumId);
if (albumId = null) {
album = new Album();
album.setId(albumId);
album.setName(rs.getString("album.name"));
albumMap.put(albumId, album);
)
PostImages pi = new PostImages();
pi.setImageId(rs.getLong("pi.image_id"));
pi.setLargePicPath(rs.getString("pi.large_pic_path"));
// Don't handle the set yourself, let Album handle it.
album.addPostImage(pi);
}
aList.addAll(albumMap.values());
As an aside: the use of table prefixes in ResultSet.getXXX is not JDBC standard and is - as far as I know - MySQL specific; it will make your code less portable between different databases.

Fetch result SQL query data to Table JAVA

I want to make jtable display my result data from SQL query , the code like this
private void TampilTabel(){
String header[] = {"No","Nama","TTL","Usia"};
DefaultTableModel tabelku = new DefaultTableModel(null, header);
Object obj[] = new Object[10];
jTable1.setModel(tabelku);
TableColumnModel columnModel = jTable1.getColumnModel();
jTable1.setRowHeight(35);
try{
stat = (Statement) koneksiMySQL.GetConnection().createStatement();
String sql = "select No_Induk, Nama, Tgl_Lahir, \n" +
"(YEAR(CURDATE()) - YEAR(Tgl_Lahir)) - (RIGHT(CURDATE(),5) < RIGHT(`Tgl_Lahir`,5))\n" +
"AS Umur\n" +
"FROM tabel_pegawai ORDER BY Nama";
rst = stat.executeQuery(sql);
while (rst.next()){
obj[0] = rst.getString("No_Induk");
obj[1] = rst.getString("Nama");
obj[2] = rst.getString("Tgl_Lahir");
obj[3] = rst.getString("No_Induk");
tabelku.addRow(obj);
}
rst.close();
}catch(SQLException ex){
JOptionPane.showMessageDialog(rootPane, "Data Tidak Ada");
}
}
Question is how to get result data without use getString(), because in my database i didnt have 'Umur' row
Thanks before
Surely you want to do
obj[3] = rst.getString("Umur");
or you could simply do by column number
obj[3] = rst.getString(4);

JDBC MYSQL FK implementation

I am trying to implement FK relation from MySQL into JAVA using JDBC. I have a list of Garaz objects and each Garaz has a list of Auto (cars) objects. I have very mixed data.
My MySQl DB is ok and I try to do it like this:
public static ArrayList <Garaz> selectRecords() throws SQLException {
Connection dbConnection = null;
Statement statement = null;
String selectTableSQL = "SELECT Garaz.G_ID, Garaz.Nazwa, Garaz.Adres, Garaz.LiczbaMiejsc, Garaz.LiczbaPoziomow, " +
"Garaz.Czynny, Auta.A_Id, Auta.Model, Auta.Kolor, Auta.IloscDrzwi, Auta.Rejestracja\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id; ";
// ArrayList lista = new ArrayList <Garaz>();
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(selectTableSQL);
// execute select SQL stetement
ResultSet rs = statement.executeQuery(selectTableSQL);
while (rs.next()) {
int g_id = rs.getInt("G_ID");
String nazwa = rs.getString("NAZWA");
String adres = rs.getString("ADRES");
int lmiejsc = rs.getInt("LICZBAMIEJSC");
int lpoz = rs.getInt("LICZBAPOZIOMOW");
boolean czynny = rs.getBoolean("CZYNNY");
ArrayList lista2 = new ArrayList <Auto>();
int a_id = rs.getInt("A_Id");
String model = rs.getString("Model");
String kolor = rs.getString("Kolor");
int ildrzwi = rs.getInt("IloscDrzwi");
String rejestracja = rs.getString("Rejestracja");
Auto d = new Auto(a_id, model, kolor, ildrzwi, rejestracja);
if (a_id !=0){
lista2.add(d);
}
Garaz f = new Garaz(g_id, nazwa, lista2, adres, lmiejsc, lpoz, czynny);
lista.add(f);
//System.out.println("nazwa : " + nazwa);
//System.out.println("adres : " + adres);
// return lista;
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
return lista;
}
I don't understand how to read from ResultSet rs in the way that: ArrayList Garaz contains objects (Garaz) and each Garaz object contains ArrayList Auto. So I have big problem with creating 2 lists (one is part of another) by reading data from rs (ResultSet). I have all Garaz and all Auto from DB tables, but the relation is mixed. Like Garaz1 contains random Auto (cars).
How do I create 2 lists (one is part of another) to keep the relation Auto is part of Garaz based on G_ID?
your result set will provide one result (aka line) for each Garaz and Auto, since thats what the select statement does. So you can...
either parse the resultset as it is, and manually create each Garaz & Auto record you want, but you will have to deal with the duplicate Garaz data.
OR
You can either use a framework like MyBatis to get the get the objects back, or.
OR
Perform a SELECT statement for the list of Garaz, then perform another SELECT statement to get the list of AUTO's back for each Garaz.
Sudo code.....
#Repository
public class StoreDbDAO
{
#Autowired
public void init(#Qualifier("dataSourceCDB") DataSource dataSource) {
this.dataSource = dataSource;
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
private static final String GET_USABLE_RECORDS = "SELECT d.ID, d.HARDWARE_ID " +
" FROM DEVICE d " +
" LEFT JOIN TABLEB o on o.X_ID = d.X_ID " +
" WHERE " +
" d.DEVC_HARDWARE_ID IS NOT NULL " +
" AND o.CODE = ? "";
public List<Map<String, Object>> getStores(String cCode)
{
return simpleJdbcTemplate.queryForList(GET_USABLE_RECORDS, code);
}
}
#Autowired
StoreDbDAO storeDbDAO;
public void caller() {
List> stores = storeDbDAO.getStores();
List<Stores> storeRecords = new ArrayList[stores.size()];
for (Map<String, Object> store: stores)
{
final String storeId = (String) store.get("HARDWARE_ID");
StoreRecord x = new StoreRecord(storeId)
storeRecords.add(x);
List<Map<String, Object>> devicesInTheStore = storeDbDAO.getDevicesForStore(storeId);
// convert these into something useful.
x.setDevicesInStore(convertToList(devicesInTheStore));
}
}
You need to iterate over the result, check if you already created the Garaz object for the G_ID of the row and either use that or create a new one. This can be simplified by sorting on the G_ID field and just create a new Garaz object when the G_ID changes.
As you comment that you don't know how to do this, here is a full example:
public List<Garaz> getAllGaraz() throws SQLException {
List<Garaz> garazList = new ArrayList<Garaz>();
try (
Connection con = getDBConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT Garaz.G_ID, /* other garaz columns */ " +
"Auta.A_Id /*other auta columns */\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id");
) {
Garaz currentGaraz = null;
while (rs.next()) {
int garazId = rs.getInt("G_ID");
// Create Garaz only if it is different
if (currentGaraz == null || currentGaraz.getId() != garazId) {
// retrieve other columns
currentGaraz = new Garaz(g_id /* + other garaz columns */);
garazList.add(currentGaraz);
}
int a_id = rs.getInt("A_Id");
// replacement of your condition of a_id != 0
// 0 could be a valid value, check for null instead
if (!rs.wasNull()) {
// retrieve other columns
Auto auta = new Auta(a_id /* + other auta columns */);
// The list of Auta is part of the garaz
currentGaraz.addAuta(auta);
}
}
return garazList;
}
}
public class Garaz {
private final List<Auta> autaList = new ArrayList<Auta>();
private final int id;
public Garaz(int g_id /* + other fields*/) {
id = g_id;
}
public int getId() {
return id;
}
public void addAuta(Auta auta) {
autaList.add(auta);
}
public List<Auta> getAutaList() {
return new ArrayList<Auta>(autaList);
}
}

Categories

Resources