Separating Logic & GUI [closed] - java
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have Java Swing application which is designed in poor architecture.
GUI, SQL Statement ... etc, all one class.
Ex. NewEmployee.java have GUI, SQL insert,update,delete & select in this class, there is no separation.
From what I read we should separate the logic from the design.
To be honest I don't know how to do that, or how to understand it.
I need to know how to break down my project so I got : model, view & controller, but I need to know what each one mean & how each one should cooperate with other.
could you help in separating this:
public class PendingOInvoices extends CFrame {
private static final long serialVersionUID = 1L;
private JToolBar toolBar = new JToolBar();
private JPanel panel_1 = new JPanel();
private JLabel label3 = new JLabel();
private CText cSearch = new CText();
private JLabel label2 = new JLabel();
private CDCombo cSearchBy = new CDCombo();
private CBGeneral cMakeBill = new CBGeneral();
private Component component5_1 = Box.createHorizontalStrut(3);
private CBRefreshE cRefresh = new CBRefreshE();
private CBCloseE cClose = new CBCloseE();
private Component component5_3 = Box.createHorizontalStrut(3);
private JLabel label1 = new JLabel();
private CDate cTDate = new CDate();
private MyOutBillingModel model1 = new MyOutBillingModel();
private JPVTableView table1 = new JPVTableView(model1);
private JLabel label = new JLabel();
private CDate cFDate = new CDate();
private CBNewE cNew = new CBNewE();
private CBModifyE cModify = new CBModifyE();
private Component component5 = Box.createHorizontalStrut(3);
private Component component5_2 = Box.createHorizontalStrut(3);
private JLabel label4 = new JLabel();
private CDCombo cFilter = new CDCombo();
public PendingOInvoices () {
setTitle("Out Patients - Pending Encounters");
setFrameIcon("opdbilling");
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
setSize(new Dimension(980, 546));
getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel_1, BorderLayout.NORTH);
panel_1.setMaximumSize(new Dimension(0, 44));
panel_1.setMinimumSize(new Dimension(0, 44));
panel_1.setLayout(null);
panel_1.setPreferredSize(new Dimension(0, 44));
panel_1.add(label3);
label3.setText("Search engine:");
label3.setBounds(790, 0, 170, 19);
panel_1.add(cSearch);
cSearch.addKeyListener(new CSearchKeyListener());
cSearch.setBounds(790, 20, 170, 23);
panel_1.add(label2);
label2.setText("Search by:");
label2.setBounds(662, 0, 127, 19);
panel_1.add(cSearchBy);
cSearchBy.addActionListener(new CSearchByActionListener());
cSearchBy.setBounds(662, 20, 127, 23);
cSearchBy.addItem("ID No");
cSearchBy.addItem("File No");
cSearchBy.addItem("Patient Name (EN)");
cSearchBy.addItem("Patient Name (ع)");
cSearchBy.addItem("Encounter No");
toolBar.setBounds(0, 0, 264, 45);
panel_1.add(toolBar);
toolBar.setFloatable(false);
toolBar.add(cRefresh);
toolBar.add(component5_1);
toolBar.add(cNew);
cNew.addActionListener(new CNewActionListener());
toolBar.add(component5_3);
toolBar.add(cModify);
cModify.addActionListener(new CModifyActionListener());
toolBar.add(component5);
toolBar.add(cMakeBill);
cMakeBill.setText("Make Bill");
cRefresh.addActionListener(new CRefreshActionListener());
cMakeBill.setIcon(SwingResourceManager.getIcon(PendingOInvoices.class, "/images/small/billmaker.png"));
cMakeBill.addActionListener(new CMakeBillActionListener());
toolBar.add(component5_2);
toolBar.add(cClose);
cClose.addActionListener(new CCloseActionListener());
panel_1.add(label1);
label1.setText("To Date:");
label1.setBounds(382, 0, 115, 19);
panel_1.add(cTDate);
cTDate.addTextListener(new CTDateTextListener());
cTDate.addKeyListener(new CTDateKeyListener());
cTDate.setBounds(382, 20, 115, 23);
getContentPane().add(table1);
table1.getJTable().addMouseListener(new table1JTableMouseListener());
table1.getJTable().addKeyListener(new Table1JTableKeyListener());
cSearch.setHorizontalAlignment(SwingConstants.CENTER);
panel_1.add(label);
label.setText("From Date:");
label.setBounds(266, 0, 115, 19);
panel_1.add(cFDate);
cFDate.setText("01/01/"+cTDate.getText().substring(7));
cFDate.addTextListener(new CFDateTextListener());
cFDate.addKeyListener(new CFDateKeyListener());
cFDate.setBounds(266, 20, 115, 23);
panel_1.add(label4);
label4.setText("Filtering Options:");
label4.setBounds(498, 0, 163, 19);
panel_1.add(cFilter);
cFilter.addActionListener(new CFilterActionListener());
cFilter.setBounds(498, 20, 163, 23);
cFilter.addItem("--- Choose ---");
cFilter.addItem("Guarantors Shares Only");
cFilter.addItem("Cash Patients Only");
cFilter.addItem("Patients Got Discount Only");
setWidths();
fillEncounters();
}
public void updateMe(String encno){
fillEncounters();
table1.getTable().requestFocus();
table1.getTable().setFocusCell(table1.search(encno, 1),1);
}
private void setWidths() {
model1.setColumnCount(9);
model1.setRowCount(0);
table1.getColumn(0).setPreferredWidth(75);
table1.getColumn(1).setPreferredWidth(90);
table1.getColumn(2).setPreferredWidth(350);
table1.getColumn(3).setPreferredWidth(80);
table1.getColumn(4).setPreferredWidth(80);
table1.getColumn(5).setPreferredWidth(80);
table1.getColumn(6).setPreferredWidth(80);
table1.getColumn(7).setPreferredWidth(80);
table1.getColumn(8).setPreferredWidth(20);
table1.getColumn(0).setHeaderValue("Date");
table1.getColumn(1).setHeaderValue("Encounter No");
table1.getColumn(2).setHeaderValue("Patient Name");
table1.getColumn(3).setHeaderValue("Total");
table1.getColumn(4).setHeaderValue("Guarantors");
table1.getColumn(5).setHeaderValue("Discount");
table1.getColumn(6).setHeaderValue("Paid");
table1.getColumn(7).setHeaderValue("Balance");
table1.getColumn(8).setHeaderValue("");
table1.setColumnType(0, JPVTable.DATE, null);
table1.setColumnType(1, JPVTable.DATE, null);
table1.setColumnType(2, JPVTable.TEXT, null);
table1.setColumnType(3, JPVTable.DOUBLE, null);
table1.setColumnType(4, JPVTable.DOUBLE, null);
table1.setColumnType(5, JPVTable.DOUBLE, null);
table1.setColumnType(6, JPVTable.DOUBLE, null);
table1.setColumnType(7, JPVTable.DOUBLE, null);
table1.setColumnType(8, JPVTable.BOOLEAN, null);
CTableConfig mc = new CTableConfig();
mc.newConfigureTable(table1,8,0,true);
table1.getTable().getColumnModel().getColumn(8).setHeaderRenderer(new CHGeneral(new MyItemListener()));
}
class MyItemListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
Object source = e.getSource();
if (!(source instanceof AbstractButton)) return;
boolean checked = e.getStateChange() == ItemEvent.SELECTED;
int rows = model1.getRowCount();
for(int x = 0; x < rows; x++){
model1.setValueAt(checked,x,8);
}
}
}
private String getSearchColumn(){
if(cSearchBy.getSelectedIndex() == 0){
return "patients.PatID";
}else if(cSearchBy.getSelectedIndex() == 1){
return "encounters.Enc_Patient";
}else if(cSearchBy.getSelectedIndex() == 2){
return "concat(patients.PatFirst,' ', patients.PatFather,' ',patients.PatMiddle,' ',patients.PatFamily)";
}else if(cSearchBy.getSelectedIndex() == 3){
return "concat(patients.PatFirstA,' ', patients.PatFatherA,' ',patients.PatMiddleA,' ',patients.PatFamilyA)";
}else if(cSearchBy.getSelectedIndex() == 4){
return "encounters.Enc_No";
}
return "";
}
private void fillEncounters(){
String currentValue = "";
int r = table1.getTable().getFocusRow();
cFDate.setFormat(2);
cTDate.setFormat(2);
String sql = "SELECT \n"
+"Date_Format(Enc_Date,'%d/%m/%Y'), \n"
+"encounters.Enc_No, \n"
+"CONCAT(' ',patients.PatFirst,' ',patients.PatFather,' ',patients.PatMiddle,' ',patients.PatFamily), \n"
+"FORMAT((Enc_Clinics+Enc_Labs+Enc_Rads+Enc_MED),2), \n"
+"FORMAT(Enc_Guarantor,2), \n"
+"FORMAT(Enc_Discount,2), \n"
+"FORMAT((Enc_Receipt-Enc_Payment),2), \n"
+"FORMAT(Enc_Balance,2), \n"
+""+Boolean.FALSE+", \n"
+"encounters.Enc_Patient, \n"
+"VERSION \n"
+"FROM \n"
+"encounters \n"
+"INNER JOIN encsummary ON encounters.Enc_No = encsummary.Enc_No \n"
+"INNER JOIN patients ON encounters.Enc_Patient = patients.PatNo \n"
+"WHERE Enc_Date Between '"+cFDate.getText()+"' AND '"+cTDate.getText()+"' AND Enc_Billed = 'false' \n"
+"AND (Enc_Clinics+Enc_Labs+Enc_Rads+Enc_MED) > 0 \n";
if(cFilter.getSelectedIndex() == 1){
sql+="and Enc_Guarantor > 0 \n";
}else if(cFilter.getSelectedIndex() == 2){
sql+="and Enc_Guarantor = 0 \n";
}else if(cFilter.getSelectedIndex() == 3){
sql+="and Enc_Discount > 0 \n";
}
if(cSearch.getText().trim().length() > 0){
sql+= "and "+getSearchColumn()+" LIKE '%"+cSearch.getText()+"%' \n";
}
sql+="Order By encounters.Enc_No DESC";
cFDate.setFormat(1);
cTDate.setFormat(1);
model1.setData(CDeclare.dataAccessor.getData(sql));
try{
currentValue = table1.getValueAt(r, 1).toString();
}catch(Exception ex){}
int i = table1.search(currentValue, 1);
table1.getTable().scrollRectToVisible(new Rectangle(table1.getTable().getCellRect(i, 1, true)));
table1.getTable().changeSelection(i, 1, false, false);
}
private class CSearchByActionListener implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
cSearchBy_actionPerformed(arg0);
}
}
private class table1JTableMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent arg0) {
table1JTable_mouseClicked(arg0);
}
}
private class CMakeBillActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cMakeBill_actionPerformed(e);
}
}
private class CSearchKeyListener extends KeyAdapter {
public void keyReleased(KeyEvent e) {
cSearch_keyReleased(e);
}
}
private class CTDateKeyListener extends KeyAdapter {
public void keyReleased(KeyEvent e) {
cTDate_keyReleased(e);
}
}
private class CRefreshActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cRefresh_actionPerformed(e);
}
}
private class CTDateTextListener implements TextListener {
public void textValueChanged(TextEvent e) {
cTDate_textValueChanged(e);
}
}
private class CCloseActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cClose_actionPerformed(e);
}
}
private class CFDateKeyListener extends KeyAdapter {
public void keyReleased(KeyEvent e) {
cFDate_keyReleased(e);
}
}
private class CFDateTextListener implements TextListener {
public void textValueChanged(TextEvent e) {
cFDate_textValueChanged(e);
}
}
private class CNewActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cNew_actionPerformed(e);
}
}
private class CModifyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cModify_actionPerformed(e);
}
}
private class Table1JTableKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
table1JTable_keyPressed(e);
}
}
private class CFilterActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
cFilter_actionPerformed(e);
}
}
protected void cSearchBy_actionPerformed(ActionEvent arg0) {
if(cSearchBy.getSelectedIndex() == 3){
cSearch.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}else{
cSearch.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
}
cSearch.setText(null);
}
protected void table1JTable_mouseClicked(MouseEvent e) {
int c = table1.getTable().getSelectedColumn();
if(e.getClickCount() >= 2 && c != 8){
cModify_actionPerformed(null);
}
}
private void insertInvoice(){
double total = 0,guarantors = 0,grandtotal = 0;
CDate datg = new CDate();
String encno = "",invno = "",version = "";
for(int i = 0; i < model1.getRowCount();i++){
if(model1.getValueAt(i, 8).equals(Boolean.TRUE)){
if(datg.getFormat() != 1){
datg.setFormat(1);
}
encno = model1.getValueAt(i, 1).toString();
version = model1.getValueAt(i, 10).toString();
if(!CDeclare.SAMEVERSION("encounters","Enc_No",encno,version)){
return;
}
CDeclare.dataAccessor.UpdateDB("update encounters set VERSION = (VERSION+1) WHERE Enc_No = '"+encno+"'");
CDeclare.doubleValue.setValue(model1.getValueAt(i,3));
total = CDeclare.doubleValue.getDouble();
CDeclare.doubleValue.setValue(model1.getValueAt(i,4));
guarantors = CDeclare.doubleValue.getDouble();
grandtotal = total-guarantors;
invno = CDeclare.newNumber.getLastYearMonthNo(datg, "LastTemp");
datg.setFormat(2);
String sql = " Insert into invoice(Inv_No,Inv_Entry_Date,Inv_Kind,Inv_ClientKind,Inv_ClientSubKind,Inv_SubRefNo,Inv_Name,Inv_Date," +
"Inv_VatPercent,Inv_SubTotal,Inv_OthersTotal,Inv_Total,EMPIII) values (" +
"'" + invno + "'," +
"'" + CDeclare.getServerDateMySSQL() + "'," +
"'" + "S" + "'," +
"'" + "P" + "'," +
"'" + "OP" + "'," +
"'" + encno + "'," +
"'" + model1.getValueAt(i, 9) + "'," +
"'" + datg.getText() + "'," +
"'" + CDeclare.VAT + "'," +
"'" + total + "'," +
"'" + guarantors + "'," +
"'" + grandtotal + "'," +
"'" + CDeclare.EMPNO + "'" + ")";
CDeclare.dataAccessor.InsertDB(sql);
insertInvDetails(encno,invno);
}
}
}
private void insertInvDetails(String encno,String invno){
CCurrency vat = new CCurrency();
String invDetSql = "SELECT \n"
+"Sec_Account, \n"
+"Sec_Department, \n"
+"Ch_Kind, \n"
+"FORMAT((SUM(Ch_Total)/("+(1+CDeclare.VAT)+")),2), \n"
+"FORMAT(SUM(Ch_Total),2) \n"
+"FROM \n"
+"enccharges \n"
+"INNER JOIN medicalsections ON Ch_Section = Sec_No \n"
+"WHERE \n"
+"Ch_EncNo = '"+encno+"' \n"
+"GROUP BY Ch_Kind,Sec_Account,Sec_Department for update \n";
Vector<?> data = CDeclare.dataAccessor.getData(invDetSql);
for(int i = 0; i < data.size(); i++){
Vector<?> v = (Vector<?>) data.elementAt(i);
CDeclare.myDouble.setValue(v.elementAt(4));
CDeclare.doubleValue.setValue(v.elementAt(3));
vat.setDouble(vat.getDouble()+CDeclare.myDouble.getDouble()-CDeclare.doubleValue.getDouble());
String insSql = "Insert into invoicedetails(Inv_No,Inv_Account,Inv_Department,Inv_Kind,Inv_Total,Inv_TaxTotal) values (" +
"'" + invno + "'," +
"'" + v.elementAt(0) + "'," +
"'" + v.elementAt(1) + "'," +
"'" + v.elementAt(2) + "'," +
"'" + CDeclare.doubleValue.getDouble() + "'," +
"'" + CDeclare.myDouble.getDouble()+ "'" + ")";
CDeclare.dataAccessor.InsertDB(insSql);
}
CDeclare.dataAccessor.UpdateDB("update invoice set Inv_Vat = '"+vat.getDouble()+"' where Inv_No = '"+invno+"'");
String sqlUpdateEncounter = " Update encounters set \n" +
" Enc_Billed = 'true',\n" +
" Enc_Status = 'D',\n" +
" Enc_BillNo = '" + invno + "'\n " +
" where Enc_No = '" + encno + "'";
CDeclare.dataAccessor.UpdateDB(sqlUpdateEncounter);
}
protected void cMakeBill_actionPerformed(ActionEvent e) {
int option = (new CConfirms()).getSelection('S',"This operation will generate temporary invoices for selected encounters \n Are you sure ?!!!");
if(option != 0){
return;
}
CDeclare.dataAccessor.initAutoCommit();
CDeclare.dataAccessor.beginTransaction();
insertInvoice();
if(CDeclare.exCounter == 0){
CDeclare.dataAccessor.endTransaction();
fillEncounters();
}else{
CDeclare.dataAccessor.rollBack();
new CAlerts('D');
}
}
protected void cSearch_keyReleased(KeyEvent e) {
fillEncounters();
}
protected void cTDate_keyReleased(KeyEvent e) {
if(cTDate.getText().length() == 10){
fillEncounters();
}
}
protected void cRefresh_actionPerformed(ActionEvent e) {
fillEncounters();
}
protected void cTDate_textValueChanged(TextEvent e) {
if(cTDate.getText().length() == 10){
fillEncounters();
}
}
protected void cClose_actionPerformed(ActionEvent e) {
dispose();
}
protected void cFDate_keyReleased(KeyEvent e) {
if(cFDate.getText().length() == 10){
fillEncounters();
}
}
protected void cFDate_textValueChanged(TextEvent e) {
if(cFDate.getText().length() == 10){
fillEncounters();
}
}
protected void cNew_actionPerformed(ActionEvent e) {
NewEncounter newr = new NewEncounter(getTitle() + " - "+cNew.getText());
newr.insertMode();
newr.setOwner(this);
newr.setVisible(true);
}
protected void cModify_actionPerformed(ActionEvent e) {
int r = table1.getTable().getFocusRow();
String encno = model1.getValueAt(r,1).toString();
NewEncounter newr = new NewEncounter(getTitle() + " - "+cModify.getText());
newr.modifyMode();
newr.setOwner(this);
newr.fillEncounter(encno);
newr.setVisible(true);
}
protected void table1JTable_keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
e.consume();
cModify_actionPerformed(null);
}
}
protected void cFilter_actionPerformed(ActionEvent e) {
fillEncounters();
}
}
class MyOutBillingModel extends PVTableModel {
private static final long serialVersionUID = 1L;
public boolean isCellEditable(int iRow, int iCol) {
try{
if(iCol == 8){
return true;
}
}catch(Exception ex){}
return false;
}
Your on the right track if you know what MVC is. You may also want to look at MVVM as it has the same goal. Let's break it down:
Model - simple classes with getter/setters and no logic or details about storage
View - classes or pages that display Model data in some organized way
Controller - the object that accepts actions from the View, manipulates Model, and transfers control to a new View (passing it a Model)
In general what we like to do is first "model" the data into classes that have no business logic, UI concepts or storage dependencies (like SQL). They are simple objects with getter/setter for data. Then the "view" classes/pages are designed so they know how to read those model objects and display them in whatever way makes sense. But the view does not know where/how those model objects are stored. The glue that puts the view and model together is the "controller", which is why it has that name. Typically the user interacts with the view to get/change data, and the view then invokes the controller with an "action" like "get-employee". The control is the only thing that knows what the action means and what to do. In the simple case, the controller will go get the data from the storage, and then decide on what the next view should be for the user. It takes the model object it loaded from storage, constructs the view, and passes the model to the view where it is rendered. The key point here is that the first view has no idea of what the controller is going to do and has no idea what the next view will be. That's all the business of the controller.
So in your case, you might have a few Employee Views like NewEmployee, EmployeeDetails, EmployeeListing. And then you might have a Model like Employee. You should be able to build these views with no SQL. That's how you know you are doing this right. Then, you introduce the Controller, like an EmployeeController. Then, you tie Button presses and click events in your Views to the action methods on the Controller. So you can add methods like this:
View listEmployees()
View createEmployee(Employee e)
View getEmployee(long id)
View deleteEmployee(long id)
Your Controller should then be the only component that interacts with storage, and then decides on what the "next" View should be. That's why it returns a View and not the Model. For instance, the method might look something like this:
public class EmployeeController {
. . .
public View listEmployees() {
List<Employee> employees = storage.getAllEmployees();
return new EmployeeListing(employees);
}
}
That's the basic concept and how the separation works. In most real MVC/MVVC frameworks, there is more sophistication around the mapping of actions and views.
Notice I also added a "storage" object so that even the Controller does not know that SQL is used. That will lead you to concepts like DAO which is how to abstract the actual storage details away from the rest of the app, if you want to.
Model View Controller (MVC) is a concept you may want to use. More about that in here: How to correctly implement swing-Please check the accepted answer in this link.
In your case, don't break the working code unless you have to...Remember that such a design change may cost more that its worth for a running system.
Start by separating all the SQL code into a separate package with interfaces and implementations. You can test those without the UI and put them aside.
Then I'd recommend making all the Swing classes another separate package. Do not call new to create and attach Listeners in the Swing classes. Instead, provide a mechanism for passing them in via constructors or setters. Inject those dependencies.
Model classes ought to represent the problem you're solving without a UI or database. See if they do.
Last have the controller package with classes that instantiate the listeners and views, gives the views the listeners they need, and fulfill the use cases by manipulating model and persistence objects.
That's MVC.
from what i read we should separate the logic from the design.
to be honest i don't know how to do that, or how to understand it.
The main reason (beyond the usual "cleaner code and architecture") why you want to do that and the principles behind can be explained best on an example.
Let's assume, you have a nice working desktop UI application. Now you want to create a web version of the very same application.
When the GUI application has placed all the business logic and all the DB accesses in the forms (or whatever the equivalent is), you got a problem. Because everything is coupled so tightly together, it is virtually impossible to re-use anything from the GUI application. So you start duplicating your code, and that's a real bad-bad. That way you end up with two code bases which have to be maintained.
In order to get the most out of the reusing game, you want to separate (at least) the UI from the underlying business logic. And while we're at it, it is also not such a bad idea to split the levels of abstraction once more and extracting the data model.
Now we can do something like this:
+-----------+
| Web UI |<<------+
+-----------+ |
| +-----------+ +------------+
+----->>| Biz Logic |<<---->>| Data Model |
| +-----------+ +------------+
+-----------+ |
| GUI |<<------+
+-----------+
To achieve that, you have to do certain things:
split the code accordingly to have independent (code) modules
remove all dependencies from right hand parts to left hand parts (ie. logic should not know anything about the UI details)
Methodical frameworks like MVC or MVVM or others can be considered as best-practice toolbelts to support you doing that at the interface between the logic and the UI parts. These concepts are proven and have matured over a long time. Strictly speaking, it is not required that you follow these concepts, but it is strongly recommended, as they not only help with architectural decisions but also and the make day-to-day coding work much easier, because of the existing framework implementations (again, that varies on what language etc. is used).
Related
Java Code never entering try block in try-catch
I am currently creating a project to write a client and service that give information from a music database. I have created a MusicService.java file which is deploying fine. I am not sure if the code is right however. I then needed to create a client. When I run the client I keep getting Error Faults thrown from my try catch in my MusicService.java class saying("Unable to find composer") or ("unable to find disc") From doing some basic debugging, I know that the try methods in getByComposer and getByDisc are never being entered and going straight to catch. I also know in my client.java method that the try is being entered due to my print statement being returned in console. However the code is never executing and going straight to the catch exception and I can't work out why. I know there is a mistake somewhere perhaps I am not calling but I have spent hours on this and can't seem to find the problem. I will leave the 2 methods underneath, if anyone could help it would be greatly appreciated. MusicService.java method package music; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class MusicService extends MusicServiceSkeleton { private final static String databaseHost = "mysql0.cs.stir.ac.uk"; private final static String databaseName = "CSCU9YW"; private final static String databasePassword = "rtk1"; private final static String databaseUser = "rtk1"; private final static String discTable = "music"; //define methods to implement the WSDL opeartions getByComposer() and getByDisc() public music.MultipleTracks getByComposer(music.Composer composer)throws ErrorFault { try { TrackDetail[]info=getByField("composer",composer.getComposer()); MultipleTracks multiTrack = new MultipleTracks(); TrackDetails multiRetrieve = new TrackDetails(); multiRetrieve.setTracklist(info); multiTrack.setMultipleTracks(multiRetrieve); return multiTrack; } catch(Exception e) { throw(new ErrorFault("Unable to find composer")); } } public music.MultipleTracks getByDisc(music.Disc disc)throws ErrorFault { try { System.out.println("hello in getbbydisc"); TrackDetail[]info=getByField("disc",disc.getDisc()); MultipleTracks multiTrack = new MultipleTracks(); TrackDetails multiRetrieve = new TrackDetails(); multiRetrieve.setTracklist(info); multiTrack.setMultipleTracks(multiRetrieve); return multiTrack; } catch(Exception e) { throw(new ErrorFault("Unable to find disc")); } } private TrackDetail[] getByField(String field, String value) throws ErrorFault { try { if (value.length() == 0) throw (new Exception(field + " is empty")); Class.forName("com.mysql.jdbc.Driver").newInstance(); String databaseDesignation = "jdbc:mysql://" + databaseHost + "/" + databaseName + "?user=" + databaseUser + "&password=" + databasePassword; Connection connection = DriverManager.getConnection(databaseDesignation); Statement statement = connection.createStatement(); String query = "SELECT disc, track, composer, work, title " + "FROM " + discTable + " " + "WHERE " + field + " LIKE '%" + value + "%'"; ResultSet result = statement.executeQuery(query); result.last(); int resultCount = result.getRow(); if (resultCount == 0) throw (new Exception(field + " '" + value + "' not found")); TrackDetail[] trackDetails = new TrackDetail[resultCount]; result.beforeFirst(); int resultIndex = 0; while (result.next()) { TrackDetail receiver = detailsReceived(result); trackDetails[resultIndex++]= receiver; } connection.close(); return (trackDetails); } catch (Exception exception) { String errorMessage = "database access error - " + exception.getMessage(); throw (new ErrorFault(errorMessage, exception)); } } private TrackDetail detailsReceived(ResultSet current)throws SQLException { TrackDetail details = new TrackDetail(); details.setDiscNumber(current.getString(1)); details.setTrackNumber(current.getString(2)); details.setComposerName(current.getString(3)); details.setWorkName(current.getString(4)); details.setTitleName(current.getString(5)); return details; } } The Client.java method package music; import music.MusicServiceStub.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Client extends JFrame implements ActionListener { private final static int contentInset = 5; private final static int trackColumns = 130; private final static int trackRows = 20; private final static int gridLeft = GridBagConstraints.WEST; private final static String programTitle = "Music Album"; private GridBagConstraints contentConstraints = new GridBagConstraints(); private GridBagLayout contentLayout = new GridBagLayout(); private Container contentPane = getContentPane(); private JButton discButton = new JButton("Check"); private JLabel discLabel = new JLabel("Disc Number:"); private JTextField discText = new JTextField(5); private JButton nameButton = new JButton("Check"); private JLabel nameLabel = new JLabel("Composer/Artiste Name:"); private JTextField nameText = new JTextField(16); private Font trackFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); private JLabel trackLabel = new JLabel("Tracks:"); private JTextArea trackArea = new JTextArea(trackRows, trackColumns); private JScrollPane trackScroller = new JScrollPane(trackArea); private MultipleTracks tracks; // define here private variable for your Client Stub public Client() throws Exception { contentPane.setLayout(contentLayout); addComponent(0, 0, gridLeft, nameLabel); addComponent(1, 0, gridLeft, nameText); addComponent(2, 0, gridLeft, nameButton); addComponent(0, 1, gridLeft, discLabel); addComponent(1, 1, gridLeft, discText); addComponent(2, 1, gridLeft, discButton); addComponent(0, 2, gridLeft, trackLabel); addComponent(0, 3, gridLeft, trackScroller); nameButton.addActionListener(this); discButton.addActionListener(this); trackArea.setFont(trackFont); trackArea.setEditable(false); // instantiate your Client Stub and assign to private class variable declared above } public static void main(String[] args) throws Exception { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int screenWidth = screenSize.width; int screenHeight = screenSize.height; Client window = new Client(); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setTitle(programTitle); window.pack(); int windowWidth = window.getWidth(); int windowHeight = window.getHeight(); int windowX = (screenWidth - windowWidth) / 2; int windowY = (screenHeight - windowHeight) / 2; window.setLocation(windowX, windowY); window.setVisible(true); } private void addComponent(int x, int y, int position, JComponent component) { Insets contentInsets = new Insets(contentInset, contentInset, contentInset, contentInset); contentConstraints.gridx = x; contentConstraints.gridy = y; contentConstraints.anchor = position; contentConstraints.insets = contentInsets; if (component == trackArea || component == trackLabel) contentConstraints.gridwidth = GridBagConstraints.REMAINDER; contentLayout.setConstraints(component, contentConstraints); contentPane.add(component); } public void actionPerformed(ActionEvent event) { String trackRows = ""; TrackDetail[] tracks; try { //System.out.println("Hello"); if (event.getSource() == nameButton) tracks = getField("composer", nameText.getText()); else if (event.getSource() == discButton) tracks = getField("disc", discText.getText()); else return; trackRows += String.format("%4s %5s %-32s %-40s %-40s\n", "Disc", "Track", "Composer/Artist", "Work", "Title"); for (int i = 0; i < tracks.length; i++) { TrackDetail trackDetail = tracks[i]; trackRows += extractMusicData(trackDetail); // extract the data for a track and append to trackRows variable } } catch (Exception exception) { String error = exception.getMessage(); if (error == null) error = exception.toString(); error = "could not get track - " + error; trackRows += error; } trackArea.setText(trackRows); } private String extractMusicData(TrackDetail track ) { String albumName= track.getWorkName(); String composer = track.getComposerName(); String title= track.getTitleName(); String trackNo= track.getTrackNumber().toString(); String discNo= track.getDiscNumber().toString(); String extractMusicTracks= String.format("%4s %5s %-32s %-40s %-40s\n", discNo, trackNo, composer, albumName, title); return extractMusicTracks; } private TrackDetail[] getField(String field, String value) throws Exception { // define behaviour for method getField() to call the web service methods and receive the results try { TrackDetail[] multiTrack; MusicServiceStub stub=new MusicServiceStub(); if(field.equals("disc")) { MusicServiceStub.Disc requestDisc = new MusicServiceStub.Disc(); requestDisc.setDisc(value); MusicServiceStub.MultipleTracks message= stub.getByDisc(requestDisc); multiTrack= extractedTracks(message); return multiTrack; } else if(field.equals("composer")); { MusicServiceStub.Composer requestComposer = new MusicServiceStub.Composer(); requestComposer.setComposer(value); MusicServiceStub.MultipleTracks message= stub.getByComposer(requestComposer); multiTrack= extractedTracks(message); return multiTrack; } } catch(Exception e) { System.out.println(e); } return null; } private TrackDetail[] extractedTracks(MultipleTracks tracks) { TrackDetails track= tracks.getMultipleTracks(); TrackDetail[] multiTrack= track.getTracklist(); return multiTrack; } }
Your error handling is way off: Idiomatic java dictates that exceptions end in the word 'Exception'. Don't use the name 'ErrorFault'. Aside from being non-idiomatic, that's a tautology. When rethrowing, pass the cause, and lose the parens: throw new ErrorFault("Unable to find composer", e); except don't name it ErrorFault. Now you can check what is causing java to jump to the catch block. Note that java does not randomly jump to catch blocks for no reason. Something in that try block is throwing, and you're hiding the cause by throwing something else without passing the original along as cause. Don't ever catch exceptions and just do 'System.out.println(e)' - code is going to continue afterwards, even though clearly the process is now in an invalid state. If you have no idea how to handle an exception, your best bet is to just add a 'throws' clause on your method to throw it onwards. If that is just not an option and you also don't feel like wrapping it in an appropriate exception either, the absolute fallback is throw new RuntimeException(e), not e.printStackTrace(), or even worse, the information-obliterating System.out.println(e); - update your IDE's templates! Once you apply the above advice, the problem should be clear. If it is not, at least now you get a stack trace that includes a lot more detail; post that as a question here (or update your question) with that info and perhaps someone can help you figure out what's going on.
Getting data from dynamically created variables in JFrame
I have a Jframe that includes a Jspinner. When the JSpinner is increased a new JTextField is created in my panel headerPanel. The script creates the textboxes with an integer attached to their variable name (tFrame0, tFrame1, and so on). Original code and all old edits moved to This pastebin. Linking the pastebin just in case it will help anyone in the future, and to not clutter the currently relevant code. This was solved with the help of TreffnonX! Thanks for being very patient with me in the comments and in chat. Here is the working code in case anybody stumbles across this kind of issue later. Global Variables private JPanel headerPanel; private JSpinner spinner; public List<JTextField> findTextFields() { List<JTextField> fields = new LinkedList<>(); Component[] children = headerPanel.getComponents(); for (Component child : children) { if (child instanceof JTextField) { JTextField childField = (JTextField) child; // check, if the name is prefixed correctly. String name = childField.getName(); if (name.startsWith(nameTField)) { fields.add(childField); } } } return fields; } JSpinner spinner = new JSpinner(); spinner.setModel(new SpinnerNumberModel(1, 1, 100, 1)); spinner.addContainerListener(new ContainerAdapter() { #Override public void componentAdded(ContainerEvent arg0) { adaptBoxes(); } }); spinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent arg0) { int spinnerValue = (Integer) spinner.getValue(); if (spinnerValue == headerPanel.getComponentCount()) { System.out.println("Error, spinner shouldn't change to same alue"); } adaptBoxes(); frame.revalidate(); frame.repaint(); } }); adaptBoxes(); adaptBoxes(); Method public void adaptBoxes() { // Find value of spinner. int spinnerValue = (Integer) spinner.getValue(); List<JTextField> textFields = findTextFields(); int numTextFields = textFields.size(); if (numTextFields > spinnerValue) { // if we have too many fields. for (JTextField textField : textFields) { String name = textField.getName(); Matcher matcher = POSTFIX_PATTERN.matcher(name); if (matcher.matches()) { String strPostfix = matcher.group(1); int postFixNumeric = Integer.parseInt(strPostfix); System.out.println("for postFix = " + postFixNumeric + ": " + textField.getText()); if (postFixNumeric >= spinnerValue) { System.out.println("PFN: " + postFixNumeric); System.out.println("FTF: " + numTextFields); headerPanel.remove(textField); } } } } else { while (numTextFields < spinnerValue) { // if we have too few fields. int hp = headerPanel.getComponentCount(); JTextField tField = new JTextField(); tField.setName(nameTField + hp); tField.getDocument().addDocumentListener(new TextFieldDocumentListener()); headerPanel.add(tField); textFields = findTextFields(); numTextFields = textFields.size(); } } } JTextField Document Listener /** * Inner class */ private final class TextFieldDocumentListener implements DocumentListener { #Override public void changedUpdate(DocumentEvent e) { warn(); } #Override public void removeUpdate(DocumentEvent e) { warn(); } #Override public void insertUpdate(DocumentEvent e) { warn(); } /** * Actual sysout to inform the user... */ public void warn() { List<JTextField> textFields = findTextFields(); for (JTextField textField : textFields) { String name = textField.getName(); Matcher matcher = POSTFIX_PATTERN.matcher(name); System.out.println(name); if (matcher.matches()) { String strPostfix = matcher.group(1); int postfixNumeric = Integer.parseInt(strPostfix); System.out.println("for postfix = " + postfixNumeric + ": " + textField.getText()); } else { System.out.println("matcher error: " + matcher); } } } }
You cannot 'append my for loop int i to a variable name', unless you want to use reflections (https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/package-summary.html). Reflections would allow you to search a java-Object for it's fields, and based on their name (if exposed) access them. Luckiely, this is not what you actually need here. You are actually looking for a way to identify the children (Components) of your J?Panel both by type and name, and then deduce the index, you formerly appended. My suggestion is to do the following: // This pattern can be anywhere in the Class-file: public static final Pattern POSTFIX_PATTERN = Pattern.compile("tFrame(\\d+)"); // This should be in your exposed GUI class (supposedly the Panel), but can be anywhere it can access headerPanel. public List<JTextField> findTextFields() { List<JTextField> fields = new LinkedList<>(); Component[] children = headerPanel.getComponents(); // this is your 'search-loop': for (Component child : children) { if (child instanceof JTextField) { JTextField childField = (JTextField) child; String name = childField.getName(); if (name.startsWith("tFrame")) { fields.add(childField); } } } return fields; } (This could also be done as with Stream, but the above code is simpler). The above code 'finds' your existing components, and you can work from there, for example by sorting them, based on their names, and then doing a print. The problem why you receive only part of your text fields seem to react to the modifications is because you (probably) don't pass the same inputData-array to the different DocumentListeners you create. if you set a breakpoint and check, I bet the inputData-Arrays have a different hash. That said, I can't deduce this 100%, since the surrounding code is incomplete. I'd suggest to change: if (tField.getText() != null) { Object[] currentData = new Object[getFieldNum + 1]; currentData[getFieldNum] = tField.getText(); inputData[getFieldNum] = tField.getText(); for (int i = 0; i < inputData.length; i++) { if (inputData[i] != null) { System.out.println("for i = " + i + ": " + inputData[i]); } } } to for (JTextField textField : findTextFields()) { String name = textField.getName(); Matcher matcher = POSTFIX_PATTERN.matcher(name); if (matcher.matches()) { String strPostfix = matcher.group(1); int postfixNumeric = Integer.parseInt(strPostfix); System.out.println("for postfix = " + postfixNumeric + ": " + textField.getText()); } } This way, you get the components at the point in time when the user actually made the change you want to react to. Also on a side note: Do you actually want to replace all existing text fields and their current state, once you reduce or increase the number on the JSpinner? Maybe consider to remove the elements that are postfixNumeric >= getTextFields().size(), or increase the number of elements without removing those that are less than the previous number on the JSpinner. That can be done with the loop you got. Edit The problem turned out to originate in a multitude of instance-fields used instead of local variables. Since the code was only partially posted, this was hard to impossible to determin from the question alone.
Drag and Drop between tables in horizontalLayout doesn't work
I've got 3 Tables in Vaadin: My Problem now is that Drag & Drop doesn't work. My Code is the following one: #Theme("valo") #SpringView(name = TaskboardView.VIEW_NAME) public class TaskboardView extends VerticalLayout implements View { private enum TableType { DONE, PROGRESS, OPEN; } private static final long serialVersionUID = 1L; private final Logger logger = LoggerFactory.getLogger(TaskboardView.class); public static final String VIEW_NAME = "taskboard"; // Components: private SprintController sprintController = new SprintController(); private TaskController taskController = new TaskController(); private Sprint sprint; private Set<Task> allTasks; private List<Task> openTasks = new ArrayList<Task>(); private List<Task> inProgressTasks = new ArrayList<Task>(); private List<Task> doneTasks = new ArrayList<Task>(); // UI Components: private Table openTable = new Table("Open Tasks:"); private int openTableId = 1; private Table inProgressTable = new Table("Tasks in Progress"); private int inProgressTableId = 1; private Table doneTable = new Table("Done Tasks"); private int doneTableId = 1; private TextField sprintName = new TextField(); private OpenTableDropHandler openTableDropHandler = new OpenTableDropHandler(); private InProgressTableDropHandler inProgressTableDropHandler = new InProgressTableDropHandler(); DoneTableHandler doneTableHandler = new DoneTableHandler(); #PostConstruct void init() { logger.info("Initializing Taskboard View..."); try { this.sprint = sprintController.getActiveSprint(); this.allTasks = sprintController.getTasksInSprint(this.sprint.getId().intValue()); sortSprintTasks(this.allTasks); this.sprintName.setNullRepresentation("-- No active Sprint found --"); this.sprintName.setValue(this.sprint.getSprintName()); this.sprintName.setWidth("800px"); this.sprintName.setReadOnly(true); this.sprintName.addStyleName("align-center"); // sets Allignment of // the textfield!!! } catch (NoActiveSprintReceivedException | NoSprintsExistException | IOException e) { logger.error("Something went wrong initializing active Sprint. The taskboard can't be displayed.", e); Notification.show("No Active Sprint found!", Notification.Type.ERROR_MESSAGE); e.printStackTrace(); return; } catch (TaskCanNotBeAllocatedException e) { logger.error("Task of sprint couldn't be allocated to an status.", e); Notification.show("Error! \n \n Task of sprint couldn't be allocated to an status.", Notification.Type.ERROR_MESSAGE); e.printStackTrace(); return; } // Layout for Sprint Name: VerticalLayout headLayout = new VerticalLayout(); headLayout.setSpacing(true); headLayout.setSizeFull(); ; headLayout.setMargin(true); headLayout.addComponent(this.sprintName); headLayout.setComponentAlignment(this.sprintName, Alignment.MIDDLE_CENTER); setSizeFull(); setSpacing(true); setMargin(true); // Layout: VerticalLayout verticalLayout = new VerticalLayout(); verticalLayout.setSpacing(true); // Layout for Board: HorizontalLayout taskBoardLayout = new HorizontalLayout(); taskBoardLayout.setSizeUndefined(); taskBoardLayout.setSpacing(true); taskBoardLayout.setMargin(true); // Adding to HorizontalLayout(TaskBoadLayout) try { initTable(this.openTable, TableType.OPEN); initTable(this.inProgressTable, TableType.PROGRESS); initTable(this.doneTable, TableType.DONE); } catch (IOException e) { logger.error("Something went wrong initizalizing Tables."); Notification.show("Error! \n \n Couldn't initialize tables.", Notification.Type.ERROR_MESSAGE); return; } taskBoardLayout.addComponent(openTable); taskBoardLayout.addComponent(inProgressTable); taskBoardLayout.addComponent(doneTable); // Adding to VerticalLayout (MainLayout) verticalLayout.addComponent(headLayout); verticalLayout.addComponent(taskBoardLayout); verticalLayout.setComponentAlignment(taskBoardLayout, Alignment.MIDDLE_CENTER); addComponent(verticalLayout); } /** * Sorts the tasks of the sprint to the required lists like open, in * Progress, done. * * #param tasks * #throws TaskCanNotBeAllocatedException */ private void sortSprintTasks(Set<Task> tasks) throws TaskCanNotBeAllocatedException { logger.info("sortSprintTask(Set<Task>tasks): Sorting Tasks to the required lists..."); for (Task t : tasks) { logger.info("Checking Sprint Status of Task >>>> " + t.getHeadLine() + " <<<<"); logger.info("Status: " + t.getStatus()); if (t.getStatus().equals(WorkflowStatusConfigurator.open)) { this.openTasks.add(t); } else if (t.getStatus().equals(WorkflowStatusConfigurator.inProgress)) { this.inProgressTasks.add(t); } else if (t.getStatus().equals(WorkflowStatusConfigurator.done)) { this.doneTasks.add(t); } else { throw new TaskCanNotBeAllocatedException( "Task can't be allocated to a sprint status: " + WorkflowStatusConfigurator.open + ", " + WorkflowStatusConfigurator.inProgress + ", " + WorkflowStatusConfigurator.done + "."); } } } #Override public void enter(ViewChangeEvent event) { // TODO Auto-generated method stub } /** * Creates the tables depending on the type parameter * * #param table * #param type * #throws IOException * #throws ClientProtocolException */ private void initTable(Table table, TableType type) throws ClientProtocolException, IOException { table.setSelectable(true); table.setImmediate(true); table.setDragMode(TableDragMode.ROW); table.addContainerProperty("ID", Long.class, null); table.setColumnWidth("ID", 50); table.addContainerProperty("Headline", String.class, null); table.setColumnWidth("Headline", 300); table.addContainerProperty("Task-Type", String.class, null); table.setColumnWidth("Task-Type", 120); table.addContainerProperty("Assignee", String.class, null); table.setColumnWidth("Assignee", 100); if (type.equals(TableType.OPEN) && this.openTasks.size() > 0) { logger.info("Loading values of Open Tasks Table..."); table.setDropHandler(this.openTableDropHandler); for (Task t : this.openTasks) { String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.openTableId); this.openTableId++; } return; } if (type.equals(TableType.PROGRESS) && this.inProgressTasks.size() > 0) { logger.info("Loading values of Progress Tasks Table..."); table.setDropHandler(this.inProgressTableDropHandler); for (Task t : this.inProgressTasks) { String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.inProgressTableId); this.inProgressTableId++; } return; } if (type.equals(TableType.DONE) && this.doneTasks.size() > 0) { logger.info("Loading values of Done Tasks Table..."); table.setDropHandler(this.doneTableHandler); for (Task t : this.doneTasks) { String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.doneTableId); this.doneTableId++; } return; } } private int giveEncreasedAvailableTableId(TableType tableType) { if(tableType.equals(TableType.OPEN)){ this.openTableId++; return this.openTableId; }else if(tableType.equals(TableType.PROGRESS)){ this.inProgressTableId++; return this.inProgressTableId; }else if(tableType.equals(TableType.DONE)){ this.doneTableId++; return this.doneTableId; }else{ return -1; } } private class OpenTableDropHandler implements DropHandler{ private static final long serialVersionUID = 1L; private final Logger logger = LoggerFactory.getLogger(OpenTableDropHandler.class); #Override public void drop(DragAndDropEvent event) { // Wrapper for the object that is dragged logger.info("Received Drag and Drop Event from OpenTable..."); DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); Object itemId = t.getItemId(); Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); try { Task taskToAdd = taskController.getById(id.intValue()); String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); if ( t.getSourceComponent() != openTable && dropData.getTarget().equals(inProgressTable)) { logger.info("Preparing Task Update to InProgress..."); openTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.OPEN)); openTasks.add(taskToAdd); inProgressTable.removeItem(itemId); inProgressTasks.remove(taskToAdd); }else if(t.getSourceComponent() != openTable && dropData.getTarget().equals(doneTable)){ logger.info("Preparing Task Update to Done..."); openTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.OPEN)); openTasks.add(taskToAdd); doneTable.removeItem(itemId); doneTasks.remove(taskToAdd); }else{ logger.info("Do nothing..."); return; } taskToAdd.setStatus(WorkflowStatusConfigurator.open); logger.info("Sending updates of taskboard to webservice..."); HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); // HttpResponse authorResponse = taskController.setAuthorInTask(taskToAdd.getAuthor().getId().intValue(), // taskToAdd.getId().intValue()); // HttpResponse assigneeResponse = taskController.setAssigneeInTask(taskToAdd.getAssignee().getId().intValue(), // taskToAdd.getId().intValue()); } catch (ClientProtocolException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } catch (IOException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } } #Override public AcceptCriterion getAcceptCriterion() { return AcceptAll.get(); } } private class InProgressTableDropHandler implements DropHandler{ private static final long serialVersionUID = 1L; private final Logger logger = LoggerFactory.getLogger(InProgressTableDropHandler.class); #Override public void drop(DragAndDropEvent event) { // Wrapper for the object that is dragged logger.info("Received Drag and Drop Event from In Progress Table."); DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); Object itemId = t.getItemId(); Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); try { Task taskToAdd = taskController.getById(id.intValue()); String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); if (t.getSourceComponent() != inProgressTable && dropData.getTarget().equals(doneTable) ){ inProgressTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.PROGRESS)); doneTable.removeItem(itemId); inProgressTasks.add(taskToAdd); doneTasks.remove(taskToAdd); }else if(t.getSourceComponent() != inProgressTable && dropData.getTarget().equals(openTable)){ inProgressTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.PROGRESS)); openTable.removeItem(itemId); inProgressTasks.add(taskToAdd); openTasks.remove(taskToAdd); }else{ return; } logger.info("Sending updates of taskboard to webservice..."); taskToAdd.setStatus(WorkflowStatusConfigurator.inProgress); HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); }catch (ClientProtocolException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } catch (IOException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } } #Override public AcceptCriterion getAcceptCriterion() { return AcceptAll.get(); } } private class DoneTableHandler implements DropHandler{ private static final long serialVersionUID = 1L; private final Logger logger = LoggerFactory.getLogger(DoneTableHandler.class); #Override public void drop(DragAndDropEvent event) { logger.info("Received Drag and Drop Event from In Done Table."); DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); Object itemId = t.getItemId(); Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); try { Task taskToAdd = taskController.getById(id.intValue()); String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); if (t.getSourceComponent() != doneTable && dropData.getTarget().equals(inProgressTable) ){ doneTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.DONE)); inProgressTable.removeItem(itemId); doneTasks.add(taskToAdd); inProgressTasks.remove(taskToAdd); }else if(t.getSourceComponent() != doneTable && dropData.getTarget().equals(openTable)){ doneTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.DONE)); openTable.removeItem(itemId); doneTasks.add(taskToAdd); openTasks.remove(taskToAdd); }else{ return; } logger.info("Sending updates of taskboard to webservice..."); taskToAdd.setStatus(WorkflowStatusConfigurator.done); HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); }catch (ClientProtocolException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } catch (IOException e) { logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); } } #Override public AcceptCriterion getAcceptCriterion() { return AcceptAll.get(); } } } Has anyone any idea or at least a clue why this doesn't work? I wrote a code following the same pattern or way and it worked fine. The only difference is that there I don't use Horizontal Layout. And now the in Progress and Done Table don't react to draggin a row on them.
Off-topic: why do you have #Theme("valo") on your view? As far as I know that's used with the UI class... On-topic: As I was saying in my comment I don't think it's related to HorizontalLayout. Either you may have misunderstood the drag source and drop target concepts or it simply slipped in the code. As it's also described in the docs the dragging starts from a source, and the event of dropping the data on the target is handled by a DropHandler. If you take a look at your sources, DoneTableHandler for example, you can see if (t.getSourceComponent() != doneTable && dropData.getTarget().equals(inProgressTable) ){ ... }else if(t.getSourceComponent() != doneTable && dropData.getTarget().equals(openTable)){ ... }else{ return; } Since you're listening for drops on your doneTable it will be the target and sources can only be the openTable or inProgressTable, not the other way around. I have a hunch that if you're going to add a log line in the else branch you'll see it on each drag & drop. Below you can see a working sample in Vaadin 7.7.3 with a HorizontalLayout and 3 tables, similar to yours. It's quick and dirty so there's room for improvement (suggestions are welcome) but (eg: position of dropped items), it supports multirow drag and also the AcceptCriterion filters drops from the source table or any other component than the expected ones: public class DragAndDropTables extends HorizontalLayout { public DragAndDropTables() { // leave some space between the tables setSpacing(true); // tables Table toDoTable = createTable("To do"); Table inProgressTable = createTable("In progress"); Table doneTable = createTable("Done"); // drop handlers which allow only drops from expected sources configureDragAndDrop(toDoTable, inProgressTable, doneTable); configureDragAndDrop(inProgressTable, toDoTable, doneTable); configureDragAndDrop(doneTable, toDoTable, inProgressTable); // some table to make sure AcceptCriterion allows drops only from expected sources Table tableNotAcceptableForDrops = createTable("Drops from here will not be accepted"); configureDragAndDrop(tableNotAcceptableForDrops); tableNotAcceptableForDrops.addItem(new Task(100, "Not droppable task")); // add some dummy data for (int i = 0; i < 10; i++) { toDoTable.addItem(new Task(i, "Task " + i)); } // add the tables to the UI addComponent(toDoTable); addComponent(inProgressTable); addComponent(doneTable); addComponent(tableNotAcceptableForDrops); } private Table createTable(String caption) { // basic table setup Table table = new Table(caption); BeanItemContainer<Task> itemContainer = new BeanItemContainer<>(Task.class); table.setContainerDataSource(itemContainer); table.setMultiSelect(true); table.setSelectable(true); table.setPageLength(10); return table; } private void configureDragAndDrop(Table table, Table... acceptedSources) { // drag & drop configuration table.setDragMode(Table.TableDragMode.MULTIROW); table.setDropHandler(new DropHandler() { #Override public void drop(DragAndDropEvent event) { // where the items are dragged from Table source = (Table) event.getTransferable().getSourceComponent(); // where the items are dragged to Table target = (Table) event.getTargetDetails().getTarget(); // unique collection of dragged tasks HashSet<Task> draggedTasks = new HashSet<>(); // https://vaadin.com/api/com/vaadin/ui/Table.TableDragMode.html // even in MULTIROW drag mode, the event contains only the row on which the drag started draggedTasks.add((Task) event.getTransferable().getData("itemId")); // we'll get the rest, if any, from the source table selection value draggedTasks.addAll((Collection<Task>) source.getValue()); // remove items from source table draggedTasks.forEach(((Table) source)::removeItem); // add items to destination table target.addItems(draggedTasks); } #Override public AcceptCriterion getAcceptCriterion() { // accept drops only from specified tables, and prevent drops from the source table return new SourceIs(acceptedSources); } }); } // basic bean for easy binding public static class Task { private String name; private int id; public Task(int id, String name) { this.name = name; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } } } Result:
Im rusty, can't figure out how to do exception handling right in Java swing
So, i have this program, and it works okey. But i have a problem. You aren't suppose to be able to add an ID that's already in the ID table in my array. This is the code for my listener on my add button (laggTill) I don't know how to make the exception stop the data from being added. So when i for example put letters in my ID box im not suppose to be able to add it. But it still does. By JOptionPane comes upp and says the error message but still add it to the array. How do i stop this from happening? I though an exception stopped everything, but apparently it doesn't. And i also need the exception for ID checking to work.. i don't know how to do it.. i haven't been doing this for a while so i can't figure it out. So, Basicly, My questions are: how do you make an exception hinder the data from being added. And how do i make my class check if the ID is unique? Main class: private class Listener implements ActionListener { String getId; #Override public void actionPerformed(ActionEvent ae) { if (ae.getSource() == laggTill) { DTODjur dto = new DTODjur(); dto.djurNamn = textFieldNamn.getText(); dto.djurKategori = (String) comboBox.getSelectedItem(); try { dto.djurID = Integer.parseInt(textFieldId.getText()); dao.laggTill(dto); } catch (WrongDjurID ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } textArea.setText("Lade till: \nID: " + textFieldId.getText() + "\nNamn: " + textFieldNamn.getText() + "\nKategori: "+ comboBox.getSelectedItem()); } DAO class: public void laggTill(DTODjur dto) throws WrongDjurID { boolean found = false; openDB(); try { int djurid = dto.djurID; String djurnamn = dto.djurNamn; String djurkategori = dto.djurKategori; String SQL = "INSERT INTO h12mjont_djur(djurID,djurNamn,djurKategori) VALUES('" + djurid + "','" + djurnamn + "','" + djurkategori + "')"; System.out.println(SQL); st.executeUpdate(SQL); found=true; } catch (SQLException ex) { } if (!found) { throw new WrongDjurID("Id ska inte innehålla bokstäver"); }else { dtodjur = getAll(); } closeDB(); dtodjur = getAll(); }
Your problem is you are catching exceptions then proceeding as if nothing had happened by writing code after the catches. I'd suggest moving all catch logic to the very end of each method. In your first block change it to this: String getId; #Override public void actionPerformed(ActionEvent ae) { if (ae.getSource() == laggTill) { DTODjur dto = new DTODjur(); dto.djurNamn = textFieldNamn.getText(); dto.djurKategori = (String) comboBox.getSelectedItem(); try { dto.djurID = Integer.parseInt(textFieldId.getText()); dao.laggTill(dto); textArea.setText("Lade till: \nID: " + textFieldId.getText() + "\nNamn: " + textFieldNamn.getText() + "\nKategori: "+ comboBox.getSelectedItem()); } catch (WrongDjurID ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } } 2nd block of code: public void laggTill(DTODjur dto) throws WrongDjurID { openDB(); try { int djurid = dto.djurID; String djurnamn = dto.djurNamn; String djurkategori = dto.djurKategori; String SQL = "INSERT INTO h12mjont_djur(djurID,djurNamn,djurKategori) VALUES('" + djurid + "','" + djurnamn + "','" + djurkategori + "')"; System.out.println(SQL); st.executeUpdate(SQL); dtodjur = getAll(); } catch (SQLException ex) { throw new WrongDjurID("Id ska inte innehålla bokstäver"); } finally { closeDB(); } } Now the getAll() call will not be run if an exception is thrown. Previously you were running getAll() even if an exception was thrown which would re-read the list. Remember to use finally clause to clean up after you read the DB regardless of if it was successful or an exception was thrown.
ORMLite examples for Android won't compile
I have been trying to work through the HelloAndroid example for ORMLite but haven't been able to successfully compile. I am having a problem with the DatabaseHelper class. Specifically the getDao() method: /** * Returns the Database Access Object (DAO) for our SimpleData class. * It will create it or return the cached value. */ public Dao<SimpleData, Integer> getDao() throws SQLException { if (simpleDao == null) { simpleDao = getDao(SimpleData.class); } return simpleDao; } Here is the compile time error I am receiving: Type parameters of D cannot be determined; no unique maximal instance exists for type variable D with upper bounds com.j256.ormlite.dao.Dao,com.j256.ormlite.dao.Dao
I got a similar error when trying to build my ormlite project using Netbeans: Compiling 15 source files to ~/NetBeansProjects/Main/build/classes Main.java:74: type parameters of D cannot be determined; no unique maximal instance exists for type variable D with upper bounds com.j256.ormlite.dao.Dao,com.j256.ormlite.dao.Dao pcDao = DaoManager.createDao(connectionSource, PC.class); Due to the comments I switched my Java Platform from OpenJDK 1.6 to Oracle's JDK 1.7.0_02 and it resolved the issue.
My solution: public class HelloAndroid extends OrmLiteBaseActivity<DatabaseHelper> { private final String LOG_TAG = getClass().getSimpleName(); /** * Called when the activity is first created. */ #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(LOG_TAG, "creating " + getClass() + " at " + System.currentTimeMillis()); TextView tv = new TextView(this); doSampleDatabaseStuff("onCreate", tv); setContentView(tv); } /** * Do our sample database stuff. */ private void doSampleDatabaseStuff(String action, TextView tv) { // get our dao RuntimeExceptionDao<SimpleData, Integer> simpleDao = getHelper().getSimpleDataDao(); // query for all of the data objects in the database List<SimpleData> list = simpleDao.queryForAll(); // our string builder for building the content-view StringBuilder sb = new StringBuilder(); sb.append("got ").append(list.size()).append(" entries in ").append(action).append("\n"); // if we already have items in the database int simpleC = 0; for (SimpleData simple : list) { sb.append("------------------------------------------\n"); sb.append("[").append(simpleC).append("] = ").append(simple).append("\n"); simpleC++; } sb.append("------------------------------------------\n"); for (SimpleData simple : list) { simpleDao.delete(simple); sb.append("deleted id ").append(simple.id).append("\n"); Log.i(LOG_TAG, "deleting simple(" + simple.id + ")"); simpleC++; } int createNum; do { createNum = new Random().nextInt(3) + 1; } while (createNum == list.size()); for (int i = 0; i < createNum; i++) { // create a new simple object long millis = System.currentTimeMillis(); SimpleData simple = new SimpleData(millis); // store it in the database simpleDao.create(simple); Log.i(LOG_TAG, "created simple(" + millis + ")"); // output it sb.append("------------------------------------------\n"); sb.append("created new entry #").append(i + 1).append(":\n"); sb.append(simple).append("\n"); try { Thread.sleep(5); } catch (InterruptedException e) { // ignore } } tv.setText(sb.toString()); Log.i(LOG_TAG, "Done with page at " + System.currentTimeMillis()); } }