I am unable to populate a JavaFX TableView object with my own data. I have attempted to modify the code found here to suit the needs of my program.
I added the table used in that tutorial, and it displays properly. I copied that code to create a second table, but cannot get my data to display in that second table.
I believe that I have properly modified the code to accept data from my SNMPInterface class. I attempt to populate my table with static data, and later with data read in from a file. Neither process works, though either will create the columns with the proper headers.
My full project can be found on GitHub.
Initially, I create a TableView object of 'SNMPInterface' class objects:
private TableView< SNMPInterface > interfaceTableView = new TableView<>();
I then create an ObservableList of SNMPInterface objects:
private final ObservableList< SNMPInterface > interfaceData =
FXCollections.observableArrayList(
new SNMPInterface( "99", "testlo" ),
new SNMPInterface( "98", "testeth1" ),
new SNMPInterface( "97", "testeth2" ),
new SNMPInterface( "96", "testbond0" )
);
Later, I create a column for the 'ifIndex' data member:
TableColumn< SNMPInterface, String > ifIndexCol = new TableColumn<>( "Index" );
ifIndexCol.setCellValueFactory( new PropertyValueFactory<>( "ifIndex" ) );
...and the second column for 'ifDescr':
TableColumn ifDescrCol = new TableColumn( "Description" );
ifDescrCol.setCellValueFactory( new PropertyValueFactory<>( "ifDescr" ) );
I then try to add it to the GridPane (named rootNode):
interfaceTableView.setItems( interfaceData );
interfaceTableView.getColumns().setAll( ifIndexCol, ifDescrCol );
rootNode.add( interfaceTableView, 0, 7, 2, 1 );
...but that does not work.
I have a loop to verify that the data is available to the method, and a second that verifies that the data is properly read in from the files. Both containers seem to have valid data, but neither makes it into my table.
My table seems to be effectively the same as the tutorial table, but obviously I am making an error somewhere. Does anyone see where my error is?
The getters and setters on the SNMPInterface class that you use for input to PropertyValueFactory should be marked public, not no modifier (otherwise the reflection logic inherent in the PropertyValueFactory won't find them).
public static class SNMPInterface {
private final SimpleStringProperty ifIndex;
private final SimpleStringProperty ifDescr;
SNMPInterface( String ifIndex, String ifDescr ) {
this.ifIndex = new SimpleStringProperty( ifIndex );
this.ifDescr = new SimpleStringProperty( ifDescr );
}
public String getIfIndex() {
return ifIndex.get();
}
public void setIfIndex( String index ) {
ifIndex.set( index );
}
public String getIfDescr() {
return ifDescr.get();
}
public void setIfDescr( String descr ) {
ifDescr.set( descr );
}
}
Related
I'm sorry this question header is not 100% correct. Because of that, I'll explain my scenario here.
I created a function to merge 4 data sets into one return format. Because that's the format front-end side needed. So this is working fine now.
public ReturnFormat makeThribleLineChart(List<NameCountModel> totalCount, List<NameCountModel>,p1Count, List<NameCountModel> p2Count, List<NameCountModel> average) {
ReturnFormat returnFormat = new ReturnFormat(null,null);
try {
String[] totalData = new String[totalCount.size()];
String[] p1Data = new String[p1Count.size()];
String[] p2Data = new String[p2Count.size()];
String[] averageData = new String[p2Count.size()];
String[] lableList = new String[totalCount.size()];
for (int x = 0; x < totalCount.size(); x++) {
totalData[x] = totalCount.get(x).getCount();
p1Data[x] = p1Count.get(x).getCount();
p2Data[x] = p2Count.get(x).getCount();
averageData[x] = average.get(x).getCount();
lableList[x] = totalCount.get(x).getName();
}
FormatHelper<String[]> totalFormatHelper= new FormatHelper<String[]>();
totalFormatHelper.setData(totalData);
totalFormatHelper.setType("line");
totalFormatHelper.setLabel("Uudet");
totalFormatHelper.setyAxisID("y-axis-1");
FormatHelper<String[]> p1FormatHelper= new FormatHelper<String[]>();
p1FormatHelper.setData(p1Data);
p1FormatHelper.setType("line");
p1FormatHelper.setLabel("P1 päivystykseen heti");
FormatHelper<String[]> p2FormatHelper= new FormatHelper<String[]>();
p2FormatHelper.setData(p2Data);
p2FormatHelper.setType("line");
p2FormatHelper.setLabel("P2 päivystykseen muttei yöllä");
FormatHelper<String[]> averageFormatHelper= new FormatHelper<String[]>();
averageFormatHelper.setData(averageData);
averageFormatHelper.setType("line");
averageFormatHelper.setLabel("Jonotusaika keskiarvo");
averageFormatHelper.setyAxisID("y-axis-2");
List<FormatHelper<String[]>> formatHelpObj = new ArrayList<FormatHelper<String[]>>();
formatHelpObj.add(totalFormatHelper);
formatHelpObj.add(p1FormatHelper);
formatHelpObj.add(p2FormatHelper);
formatHelpObj.add(averageFormatHelper);
returnFormat.setData(formatHelpObj);
returnFormat.setLabels(lableList);
returnFormat.setMessage(Messages.Success);
returnFormat.setStatus(ReturnFormat.Status.SUCCESS);
} catch (Exception e) {
returnFormat.setData(null);
returnFormat.setMessage(Messages.InternalServerError);
returnFormat.setStatus(ReturnFormat.Status.ERROR);
}
return returnFormat;
}
so, as you can see here, all the formatting is hardcoded. So my question is how to automate this code for list count. Let's assume next time I have to create chart formatting for five datasets. So I have to create another function to it. That's the thing I want to reduce. So I hope you can understand my question.
Thank you.
You're trying to solve the more general problem of composing a result object (in this case ReturnFormat) based on dynamic information. In addition, there's some metadata being setup along with each dataset - the type, label, etc. In the example that you've posted, you've hardcoded the relationship between a dataset and this metadata, but you'd need some way to establish this relationship for data dynamically if you have a variable number of parameters here.
Therefore, you have a couple of options:
Make makeThribleLineChart a varargs method to accept a variable number of parameters representing your data. Now you have the problem of associating metadata with your parameters - best option is probably to wrap the data and metadata together in some new object that is provided as each param of makeThribleLineChart.
So you'll end up with a signature that looks a bit like ReturnFormat makeThribleLineChart(DataMetadataWrapper... allDatasets), where DataMetadataWrapper contains everything required to build one FormatHelper instance.
Use a builder pattern, similar to the collection builders in guava, for example something like so:
class ThribbleLineChartBuilder {
List<FormatHelper<String[]>> formatHelpObj = new ArrayList<>();
ThribbleLineChartBuilder addDataSet(String describeType, String label, String yAxisId, List<NameCountModel> data) {
String[] dataArray = ... ; // build your array of data
FormatHelper<String[]> formatHelper = new FormatHelper<String[]>();
formatHelper.setData(dataArray);
formatHelper.setType(describeType);
... // set any other parameters that the FormatHelper requires here
formatHelpObj.add(formatHelper);
return this;
}
ReturnFormat build() {
ReturnFormat returnFormat = new ReturnFormat(null, null);
returnFormat.setData(this.formatHelpObj);
... // setup any other fields you need in ReturnFormat
return returnFormat;
}
}
// usage:
new ThribbleLineChartBuilder()
.addDataSet("line", "Uudet", "y-axis-1", totalCount)
.addDataSet("line", "P1 päivystykseen heti", null, p1Count)
... // setup your other data sources
.build()
public static void loadUser(String txtFieldName, String txtFeildPassword) throws FileNotFoundException {
File file = new File( "C:\\Users\\obiak\\Documents\\fall 2018\\application Programming\\JavaFX Workspace"
+ "\\obp937-lab5\\src\\main\\resources\\data\\users.csv" );
Scanner scan = new Scanner(file);
ArrayList<User> user = new ArrayList<>();
while( scan.hasNextLine() ) {
String line = scan.nextLine();
String [] token = line.split(",");
String name = token[0];
String pass = token[1];
String wood = token[2];
String core = token[3];
String length = token[4];// remember to change file back to 8.5 and ammend constructors also
String quality = token[5];
User newUser = new User(name, pass, wood, core, length, quality);
user.add(newUser);
}
scan.close();
System.out.println("I am here now");
System.out.println("Right");
for(int i=0; i<user.size(); i++) {
if ( txtFieldName.equals(user.get(i).getName()) && txtFeildPassword.equals(user.get(i).getName()) ) {
WandShopController wandShopController = new WandShopController();
FXMLLoader loader = new FXMLLoader( );
loader.setLocation(WandShopController.class.getResource("Scene1FXML.fxml"));
loader.setController(loader);
wandShopController.loaduserBox(user.get(i).getWood(), user.get(i).getCore(), user.get(i).getLength(),user.get(i).getQuality());
System.out.println("Still working");
}
System.out.println(" good job");
}
}
this is the part of the code that gets user information to populate the Combobox. it is declared and defined in a NON-controler class. the code gets the user information alright, then passes it to a method called "loadUserBox" defined in the controller class.The code works up until it needs to pass the details to the controller class method. It does not fail but it just doesnt populate the comboBox. Am i calling the controller method wrongly? please help with explanations thanks. And i am using scene builder, JavaFX, FXML
public void loaduserBox(String wood, String core, String length, String quality) {
ObservableList<String> list = FXCollections.observableArrayList( wood, core, length, quality);
System.out.println("Whats wrong");
woodBox.getItems().clear();
woodBox.getItems().addAll(list);
}
//this part of the code takes in information to populate the comboBox. the comboBox has already been declared in the same controller class I am referring to
There are three problems here.
Firstly, your FXMLLoader (loader) does not call the load() method, so nothing is actually loaded. I'm not sure if this is missing because you are trying to copy a small portion of your original codes out.
Secondly, you called loader.setController(loader), which effectively made the FXMLLoader the controller. Notice that you didn't use wandShopController after calling wandShopController.loaduserBox().
So this is what you need:
WandShopController wandShopController = new WandShopController();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(WandShopController.class.getResource("Scene1FXML.fxml"));
loader.setController(wandShopController); // Set the correct controller
loader.load(); // You probably need to store the root node, depending on what you are trying to do
wandShopController.loaduserBox(user.get(i).getWood(), user.get(i).getCore(), user.get(i).getLength(),user.get(i).getQuality());
Lastly, it seems that you are loading a console application (therefore the use of Scanner), but later on it becomes a JavaFX application with GUI. I'm not too sure how you managed to do that, but that definitely looks like a problem to me.
First of all, I'm not sure about if the title or the tags are correct. If not, someone please correct me
My question is if there are any tools or ways to create an autocomplete list with items from an external source, having netbeans parsing it and warn me if there are any errors.
-- The problem: I use JDBC and I want to model somehow all my schemas, tables and columns so that netbeans can parse it and warn me if I have anything wrong. For example with a normal use of JDBC I would had a function:
ResultSet execSelect( String cols, String table ){
return statement.executeQuery("SELECT "+cols+" FROM "+table); }
The problem is that someone should know exactly what are the available params for that to pass the correct strings.
I would like netbeans to show me somehow an autocomplete list with all available options.
PS. I had exactly the same problem when I was building a web application and I wanted somehow to get all paths for my external resources like images, .js files, .css files etc.
-- Thoughts so far:
My thoughts till now were to put a .java file with public static final String vars with some how nested static classes so that I could access from anywhere. For example:
DatabaseModel.MySchema.TableName1.ColumnName2
would be a String varialble with the 'ColumnName2' column and 'TableName1' table. That would help me with autocompletes but the problem is that there is no type checking. In other words someone could use any string, global defined or not as a table and as a column which is not correct either. I'm thinking to use nested enums somehow to cover these cases about type checking but I'm not sure if that would be a good solution in any case.
Any thoughts?
Finally I came up with writting a "script" that connects to mysql gets all meta data (every column of every table of every schema) and creates a java file with predefined classes and Strings that describes the model. For example:
- If you want the name of the column C1 from table T1 from schema S1 you would type DatabaseModel.S1.T1.C1._ which is a public static final String with the column name.
- If you want the table T2 from schema S2 you would type DatabaseModel.S2.T2 which is a class that implements DatabaseTable interface. So the function: execSelect could take a DatabaseTable and a DatabaseColumn as a parameter.
Here is the code (not tested but the idea is clear I think).
public static void generateMysqlModel(String outputFile) throws IOException, SQLException{
//** Gather the database model
// Maps a schema -> table -> column
HashMap<String,HashMap<String,ArrayList<String>>> model =
new HashMap<String,HashMap<String,ArrayList<String>>>();
openDatabase();
Connection sqlConn = DriverManager.getConnection(url, username, password);
DatabaseMetaData md = sqlConn.getMetaData();
ResultSet schemas = md.getSchemas(); // Get schemas
while( schemas.next() ){ // For every schema
String schemaName = schemas.getString(1);
model.put( schemaName, new HashMap<String,ArrayList<String>>() );
ResultSet tables = md.getTables(null, null, "%", null); // Get tables
while (tables.next()) { // For every table
String tableName = tables.getString(3);
model.get(schemaName).put( tableName, new ArrayList<String>() );
// Get columns for table
Statement s = sqlConn.createStatement(); // Get columns
s.execute("show columns in "+tables.getString(3)+";");
ResultSet columns = s.getResultSet();
while( columns.next() ){ // For every column
String columnName = columns.getString(1);
model.get(schemaName).get(tableName).add( columnName );
}
}
}
closeDatabase();
//** Create the java file from the collected model
new File(outputFile).createNewFile();
BufferedWriter bw = new BufferedWriter( new FileWriter(outputFile) ) ;
bw.append( "public class DatabaseModel{\n" );
bw.append( "\tpublic interface DatabaseSchema{};\n" );
bw.append( "\tpublic interface DatabaseTable{};\n" );
bw.append( "\tpublic interface DatabaseColumn{};\n\n" );
for( String schema : model.keySet() ){
HashMap<String,ArrayList<String>> schemaTables = model.get(schema);
bw.append( "\tpublic static final class "+schema+" implements DatabaseSchema{\n" );
//bw.append( "\t\tpublic static final String _ = \""+schema+"\";\n" );
for( String table : schemaTables.keySet() ){
System.out.println(table);
ArrayList<String> tableColumns = schemaTables.get(table);
bw.append( "\t\tpublic static final class "+table+" implements DatabaseTable{\n" );
//bw.append( "\t\t\tpublic static final String _ = \""+table+"\";\n" );
for( String column : tableColumns ){
System.out.println("\t"+column);
bw.append( "\t\t\tpublic static final class "+column+" implements DatabaseColumn{"
+ " public static final String _ = \""+column+"\";\n"
+ "}\n" );
}
bw.append( "\t\t\tpublic static String val(){ return this.toString(); }" );
bw.append( "\t\t}\n" );
}
bw.append( "\t\tpublic static String val(){ return this.toString(); }" );
bw.append( "\t}\n" );
}
bw.append( "}\n" );
bw.close();
}
PS. For the resources case in a web application I guess someone could get all files recursively from the "resources" folder and fill in the model variable. That will create a java file with the file paths. The interfaces in that case could be the file types or any other "file view" you want.
I also thought that it would be useful to create the .java file from an XML file for any case, so anyone would just create some kind of defintion in an xml file for that purpose.
If someone implements anything like that can post it here.
Any comments/improvements will be welcomed.
I have a pretty big swing application and i want to make it remember sizes of all windows, jframes etc. So if user resized window how he likes, next time the window looks exact the same way.
Do i have a better option to solve it, but manually write the position/size of each window in Preferences? Is there any convinient way to store the order of columns in JTable? May be some framework? Just don't want to write boilerplate.
Serialization of the whole big app is unfortunately not an option.
No, there isn't. Don't forget to write the bounds (position/size) of the main JFrame.
And after restoring window position don't forget to check if the position is really in displayed desktop area. The screen configuration may change between application runs (eg. when the user disconnects laptop from a desktop monitor).
Is there a better option than to write the position/size of each window in Preferences?
No, there isn't. Don't forget to write the bounds (position/size) of the main JFrame. You could write the parameters to an XML file instead of a preferences file, but that's an implementation detail.
Is there any convenient way to store the order of columns in a JTable?
Write the column names and positions out to your preferences file.
While this task is common, the implementation of this task is dependent on what you want to save from your GUI.
The way I would save these GUI parameters would be to create a model class that contains all of the bounds and other parameters that you're interested in saving. I would read a XML file that contains these parameters and populate the fields in the model class. If there's no file, I'd set defaults.
The GUI would use the fields in the model class to build the GUI. As the user modifies the GUI, I'd update the model class with the new values.
When the user closes the GUI, I'd write out the model class to an XML file.
I prefer using XML files over properties files because it's easier to see the structure of the model, and I find XML files easier to modify when the GUI changes.
Here's a start. The following code will find the top-most container and save the bounds of all child components to a preferences file which can then be used to restore. This probably won't handle all situations but it works for my app. Future changes can be tracked here.
public class WindowBoundsRestorer
{
private final String filename;
private Properties properties;
public WindowBoundsRestorer( String filename )
{
this.filename = filename;
}
private void setBounds( String key, Component c )
{
key = key + c.getName();
String position = properties.getProperty( key );
if ( c.getName() != null && ! StringUtils.isBlank( position ) )
{
String[] nums = position.split( "," );
c.setBounds( Integer.parseInt( nums[0] ), Integer.parseInt( nums[1] ),
Integer.parseInt( nums[2] ), Integer.parseInt( nums[3] ) );
}
if ( c instanceof Container )
{
key = key + "/";
Container container = (Container) c;
for ( Component child : container.getComponents() )
setBounds( key, child );
}
}
/**
* Loads the properties from the .xml file and sets all named windows with a matching
* name.
*
* #param component Any component in the Swing app. The top-most container will be
* determined from this component.
*/
public void restore( Component component )
{
properties = new Properties();
InputStream is = null;
try
{
is = new FileInputStream( filename );
properties.loadFromXML( is );
}
catch ( IOException e )
{
e.printStackTrace();
return;
}
finally
{
IOUtils.closeQuietly( is );
}
Component top = component;
while ( top.getParent() != null )
top = top.getParent();
setBounds( "", top );
}
private void getBounds( String key, Component c )
{
key = key + c.getName();
String position = String.format( "%d,%d,%d,%d", c.getX(), c.getY(), c.getWidth(), c.getHeight() );
properties.setProperty( key, position );
if ( c instanceof Container )
{
key = key + "/";
Container container = (Container) c;
for ( Component child : container.getComponents() )
getBounds( key, child );
}
}
public void save( Component component )
{
Component top = component;
while ( top.getParent() != null )
top = top.getParent();
properties = new Properties();
getBounds( "", top );
OutputStream os = null;
try
{
os = new FileOutputStream( filename );
properties.storeToXML( os, "Browser" );
}
catch ( IOException e )
{
e.printStackTrace();
}
finally
{
IOUtils.closeQuietly( os );
}
}
}
Whatever you want to remember on the next invocation (window position, etc.) write to a file, and read that file from start up. It's going to need to be persisted to disk, nobody knows what you really want saved (probably not the time sensitive data), and any "automatic" solution can't work unless it also saves the time-sensitive data.
Would you want your application to restore with a record displayed that had been deleted? Probably not.
I've always used java.util.Preferences for this, but a javax.jnlp.PersistenceService works "even for applications that are running in the restricted execution environment."
I want to store the Arraylist values into database(postgresql database) in java.
ArrayList<String> ActiveProcess = new ArrayList<String>();
ArrayList<String> InActiveProcess = new ArrayList<String>();
I want to store the details in a database ProcessInfo table with following fields Process Name, Process Status, Email Sent, SMS Sent, LastModifiedTime. The ActiveProcess contains the process names are server.exe, Receiver.exe .etc its process status is true,Email Sent, SMS Sent is false.
The InActiveProcess contains the process names are SmsReceiver.exe, sender.exe .etc its process status is false ,Email Sent, SMS Sent is true .
How to do this..? Thank in advance.
build model class to facilitates storing process information in DB:
public class Process {
public static enum TYPE { ACTIVE , NOT_ACTIVE } ;
private ArrayList<String> names ;
private String emailSent emailSent ;
private Date lastModification ;
private Boolean status ;
private TYPE type ;
//
// provide constructors + setter + getter methods
//
}
to store process in DB , use:
public void saveProcess (Process p) {
ArrayList<String> name = p.getProcessesName(); // or you can get iterator from the arraylist
String emailSent = p.getEmailSent();
Date lastModification = p.getLastModification();
Boolean status = p.getStatus();
//
// use SQL insert statements to save info
//
}
to get all processes:
public ArrayList<Process> getAllProcesses () {
ArrayList<Process> processes = new ArrayList<Process>();
//
// use SQL select statement to get processes
//
return proceses ;
}
or you can pass TYPE to the method to get the active or non active processes.
The best way is to keep it simple and avoid unnormal database design. So I would suggest a new table with two column (id, value) referenced by the main table using id