I have a JTabbedPane like the one in this picture:
I have a class for each tab (HouseGUI, CSPGUI, VPPGUI, and many others).
Each class has a method called writeToXML()
I need to call the writeToXML() method of each "class" in my JTabbedPane when I press the "Save All" button. But I don't really know how to do it. Can you help me?
Here's what I've done so far:
if (e.getSource() == saveAllButton) {
int totalTabs = tabbedPane.getTabCount();
ArrayList<ArrayList<String>> salvationForAll = new ArrayList<>();
ArrayList<Method> methods = new ArrayList<>();
Method[] array = new Method[50];
for (int i = 0; i < totalTabs; i++) {
try {
String title = tabbedPane.getTitleAt(i);
String tmp = title;
tmp = tmp.replaceAll("\\s", "");
array = Class.forName("tabbedpaneInterfaces."+ tmp +"GUI").getMethods();
} catch (ClassNotFoundException ex) {
Logger.getLogger(AddComponents.class.getName()).log(Level.SEVERE, null, ex);
}
methods = convertToArrayList(array);
int methodSize = methods.size();
for (int j = 0; j < methodSize; j++) {
//TO DO call WriteToXML()
}
}
}
How can I call the methods I need, in runtime?
Make all you *UI classes implements the same interface :
public interface XMLWritable {
void writeToXml();
}
public class HouseGUI implements XMLWritable {
public void writeToXml() {
//XML writing stuff
}
}
----
for (int i = 0; i < totalTabs; i++) {
if(tabbedPane.getComponentAt(i) instanceof XMLWritable ) {
((XMLWritable) tabbedPane.getComponentAt(i)).writeToXml();
}
}
To conclude, it is not very maintainable to mix UI and persistence stuffs, but it is not the purpose of your question.
Related
I have a custom ArrayList and String ArrayList in my Android application. I am using one for-loop for adding custom list values to sqlite. I also remove rows in the custom ArrayList which will match with the value of the String ArrayList before adding to sqlite. I have to use two for-loops for this matter. Can I achieve this inside the sqlite adding loop?
ArrayList<String> localRefNoList = new ArrayList<>();
ArrayList<SynchronizDTO> arr_sync = new ArrayList<>();
public class SynchronizDTO {
private String userName;
private String referenceNo;
private String employeeNo;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getReferenceNo() {
return referenceNo;
}
public void setReferenceNo(String referenceNo) {
this.referenceNo = referenceNo;
}
public String getEmployeeNo() {
return employeeNo;
}
public void setEmployeeNo(String employeeNo) {
this.employeeNo = employeeNo;
}
}
for (int i = 0; i < arr_sync.size(); i++) {
for (String ss : localRefNoList) {
if (ss.equals(arr_sync.get(i).getReferenceNo().trim())) {
arr_sync.remove(i);
}
}
}
for (int i = 0; i < arr_sync.size(); i++) {
ContentValues cv = new ContentValues();
cv.put(DatabaseHelper.userName, arr_sync.get(i).getUserName().trim());
cv.put(DatabaseHelper.referenceNo, arr_sync.get(i).getReferenceNo().trim());
cv.put(DatabaseHelper.employeeNo, arr_sync.get(i).getEmployeeNo().trim());
try {
restoreLogRes = db.insertOrThrow(DatabaseHelper.tbl_sms, null, cv);
} catch (Exception ex) {
}
}
You can add a flag variable to do this in one go. And it will be much more intuitional if you do it on the removing loop rather than sqlite adding loop. Here I am optimizing a little bit. Also remember don't call for (int i = 0; i < arr_sync.size(); i++) here. It will calculate list size again and again. Rather do this :
int length = arr_sync.size();
for (int i = 0; i < length; i++) {
boolean flag = true;
for (String ss : localRefNoList) {
if (ss.equals(arr_sync.get(i).getReferenceNo().trim())) {
arr_sync.remove(i);
flag = false;
break;
}
}
if(flag){
ContentValues cv = new ContentValues();
cv.put(DatabaseHelper.userName, arr_sync.get(i).getUserName().trim());
cv.put(DatabaseHelper.referenceNo,
arr_sync.get(i).getReferenceNo().trim());
cv.put(DatabaseHelper.employeeNo, arr_sync.get(i).getEmployeeNo().trim());
try {
restoreLogRes = db.insertOrThrow(DatabaseHelper.tbl_sms, null, cv);
} catch (Exception ex) {
}
}
}
I want to implement Singleton in a Java class who call the onCall Method in Mule ,
There is my java code
public class MyClass implements Callable {
#Override
public LinkedList<File> onCall(MuleEventContext eventContext) throws Exception {
String fileDirectory = eventContext.getMessage().getInvocationProperty("directory");
String fileDestination = eventContext.getMessage().getInvocationProperty("destination");
LinkedList<File> fileList = (LinkedList<File>) FileUtils.listFiles(new File(fileDirectory), null, false);
for (int j = 0; j < fileList.size(); j++) {
if (fileList.get(j).length() == 0) {
eventContext.getMessage().setOutboundProperty("logger",
"The file was moved to " + fileDestination);
FileUtils.moveFileToDirectory(fileList.get(j), new java.io.File(fileDestination), false);
}
}
fileList = (LinkedList<File>) FileUtils.listFiles(new File(fileDirectory), null, false);
return fileList;
}
}
I was given exercise that I need to refactor several java projects.
Only those 2 left which I truly don't have an idea how to refactor.
csv.writer
public class CsvWriter {
public CsvWriter() {
}
public void write(String[][] lines) {
for (int i = 0; i < lines.length; i++)
writeLine(lines[i]);
}
private void writeLine(String[] fields) {
if (fields.length == 0)
System.out.println();
else {
writeField(fields[0]);
for (int i = 1; i < fields.length; i++) {
System.out.print(",");
writeField(fields[i]);
}
System.out.println();
}
}
private void writeField(String field) {
if (field.indexOf(',') != -1 || field.indexOf('\"') != -1)
writeQuoted(field);
else
System.out.print(field);
}
private void writeQuoted(String field) {
System.out.print('\"');
for (int i = 0; i < field.length(); i++) {
char c = field.charAt(i);
if (c == '\"')
System.out.print("\"\"");
else
System.out.print(c);
}
System.out.print('\"');
}
}
csv.writertest
public class CsvWriterTest {
#Test
public void testWriter() {
CsvWriter writer = new CsvWriter();
String[][] lines = new String[][] {
new String[] {},
new String[] { "only one field" },
new String[] { "two", "fields" },
new String[] { "", "contents", "several words included" },
new String[] { ",", "embedded , commas, included",
"trailing comma," },
new String[] { "\"", "embedded \" quotes",
"multiple \"\"\" quotes\"\"" },
new String[] { "mixed commas, and \"quotes\"", "simple field" } };
// Expected:
// -- (empty line)
// only one field
// two,fields
// ,contents,several words included
// ",","embedded , commas, included","trailing comma,"
// """","embedded "" quotes","multiple """""" quotes"""""
// "mixed commas, and ""quotes""",simple field
writer.write(lines);
}
}
test
public class Configuration {
public int interval;
public int duration;
public int departure;
public void load(Properties props) throws ConfigurationException {
String valueString;
int value;
valueString = props.getProperty("interval");
if (valueString == null) {
throw new ConfigurationException("monitor interval");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("monitor interval > 0");
}
interval = value;
valueString = props.getProperty("duration");
if (valueString == null) {
throw new ConfigurationException("duration");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("duration > 0");
}
if ((value % interval) != 0) {
throw new ConfigurationException("duration % interval");
}
duration = value;
valueString = props.getProperty("departure");
if (valueString == null) {
throw new ConfigurationException("departure offset");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("departure > 0");
}
if ((value % interval) != 0) {
throw new ConfigurationException("departure % interval");
}
departure = value;
}
}
public class ConfigurationException extends Exception {
private static final long serialVersionUID = 1L;
public ConfigurationException() {
super();
}
public ConfigurationException(String arg0) {
super(arg0);
}
public ConfigurationException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public ConfigurationException(Throwable arg0) {
super(arg0);
}
}
configuration.test
public class ConfigurationTest{
#Test
public void testGoodInput() throws IOException {
String data = "interval = 10\nduration = 100\ndeparture = 200\n";
Properties input = loadInput(data);
Configuration props = new Configuration();
try {
props.load(input);
} catch (ConfigurationException e) {
assertTrue(false);
return;
}
assertEquals(props.interval, 10);
assertEquals(props.duration, 100);
assertEquals(props.departure, 200);
}
#Test
public void testNegativeValues() throws IOException {
processBadInput("interval = -10\nduration = 100\ndeparture = 200\n");
processBadInput("interval = 10\nduration = -100\ndeparture = 200\n");
processBadInput("interval = 10\nduration = 100\ndeparture = -200\n");
}
#Test
public void testInvalidDuration() throws IOException {
processBadInput("interval = 10\nduration = 99\ndeparture = 200\n");
}
#Test
public void testInvalidDeparture() throws IOException {
processBadInput("interval = 10\nduration = 100\ndeparture = 199\n");
}
#Test
private void processBadInput(String data) throws IOException {
Properties input = loadInput(data);
boolean failed = false;
Configuration props = new Configuration();
try {
props.load(input);
} catch (ConfigurationException e) {
failed = true;
}
assertTrue(failed);
}
#Test
private Properties loadInput(String data) throws IOException {
InputStream is = new StringBufferInputStream(data);
Properties input = new Properties();
input.load(is);
is.close();
return input;
}
}
Ok, here some advice regarding the code.
CsvWriter
The bad thing is that you print everything to System.out. It will be hard to test without mocks. Instead I suggest you to add field PrintStream which defines where all data will go.
import java.io.PrintStream;
public class CsvWriter {
private final PrintStream printStream;
public CsvWriter() {
this.printStream = System.out;
}
public CsvWriter(PrintStream printStream) {
this.printStream = printStream;
}
...
You then write everything to this stream. This refactoring easy since you use replace function(Ctrl+R in IDEA). Here is the example how you do it.
private void writeField(String field) {
if (field.indexOf(',') != -1 || field.indexOf('\"') != -1)
writeQuoted(field);
else
printStream.print(field);
}
Others stuff seems ok in this class.
CsvWriterTest
First thing first you don't check all logic in a single method. Make small methods with different kind of tests. It's ok to keep your current test though. Sometimes it's useful to check most of the logic in a complex scenario.
Also pay attention to the names of the methods. Check this
Obviously you test doesn't check the results. That's why we need this functionality with PrintStream. We can build a PrintStream on top of the instance of ByteArrayOutputStream. We then construct a string and check if the content is valid. Here is how you can easily check what was written
public class CsvWriterTest {
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private PrintStream printStream = new PrintStream(byteArrayOutputStream);
#Test
public void testWriter() {
CsvWriter writer = new CsvWriter(printStream);
... old logic here ...
writer.write(lines);
String result = new String(byteArrayOutputStream.toByteArray());
Assert.assertTrue(result.contains("two,fields"));
Configuration
Make fields private
Make messages more concise
ConfigurationException
Seems good about serialVersionUID. This thing is needed for serialization/deserialization.
ConfigurationTest
Do not use assertTrue(false/failed); Use Assert.fail(String) with some message which is understandable.
Tip: if you don't have much experience and need to refactor code like this, you may want to read some chapters of Effective Java 2nd edition by Joshua Bloch. The book is not so big so you can read it in a week and it has some rules how to write clean and understandable code.
With the java.util.prefs.Preferences API is it possible to get historic results which are older than the last entry?
eg if you had
prefs.put("key", "value1");
prefs.put("key", "value2");
return prefs.get("key");
will return "value2"
Can I ever get "value1" ?
If no then what is the best alternative to achieve this functionality.
If anyone can do better I am happy to accept their answer, in the mean time:
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
public class RecentStrings
{
private final Preferences prefs;
private final int noRecent;
private static final int defaultNo = 10;
private final String indexingKey;
public RecentStrings()
{
this(Preferences.userRoot(), defaultNo, "r");
}
public RecentStrings(Preferences prefs, int noRecent, String indexingKey)
{
this.noRecent = noRecent;
this.prefs = prefs;
this.indexingKey = indexingKey;
}
public void setMostRecentString(String file)
{
if (!getAllRecentStrings().contains(file))
{
for (int i = noRecent-1; i >= 0; i--)
{
prefs.put(indexingKey+(i+1), prefs.get(indexingKey+i, ""));
}
prefs.put(indexingKey+0, file);
}
else
{
removeRecentString(file);
setMostRecentString(file);
}
}
private void removeRecentString(String file)
{
List<String> recents = getAllRecentStrings();
recents.remove(file);
for (int i=0; i < noRecent; i++)
{
String value;
if (i < recents.size())
{
value = recents.get(i);
}
else
{
value = "";
}
prefs.put(indexingKey+i,value);
}
}
public String getMostRecentString()
{
return prefs.get(indexingKey+0, "");
}
public List<String> getAllRecentStrings()
{
List<String> mostRecent = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
String value = prefs.get(indexingKey+i, "");
if (!value.equals(""))
{
mostRecent.add(value);
}
}
return mostRecent;
}
}
Which also handles duplicates and keeps things from most recent to oldest.
I have a class in Java which is written bellow.I want to know does that has normal size or it is big and huge and should be broken into some pieces:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
public class AddressTree
{
private AddressNode structureRoot, userRoot;
private String xmlAddress;
public AddressTree(String XMLaddress)
{
this.xmlAddress = XMLaddress;
createEmptyTree();
startParsing();
}
private void startParsing()
{
AddressXMLParser handler = new AddressXMLParser(this);
try
{
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
File xml = new File(xmlAddress);
parser.parse(xml, handler);
ArrayList<AddressNode> rawNodes = createRawNodes(handler.getAddressStructure());
createTreeFromRawNodes(rawNodes, handler.getStartItem());
for (int i = 0; i < handler.getFinalItems().size(); i++)
{
getAddressNode(handler.getFinalItems().get(i), structureRoot).setIsFinal(true);
}
}
catch (StartAddressNodeNotFoundException ex)
{
Logger.getLogger(AddressTree.class.getName()).log(Level.SEVERE, null, ex);
}
catch (ParserConfigurationException ex)
{
}
catch (SAXException ex)
{
}
catch (IOException ex)
{
}
}
private void createEmptyTree()
{
structureRoot = new AddressNode("root", null);
userRoot = new AddressNode("root", null);
}
public void setValue(String nodeName, String value) throws AddressNodeNotFoundException
{
AddressNode node = getAddressNode(nodeName, userRoot);
if (node != null)
{
node.setNodeValue(value);
}
else
{
throw new AddressNodeNotFoundException();
}
}
public ArrayList<String> getCompleteAddress()
{
return null;
}
public boolean isAddressCompleted()
{
AddressNode iterator = userRoot;
while (iterator.getAllChilds().size() != 0)
{
iterator = iterator.getAllChilds().get(0);
}
if (getAddressNode(iterator.getNodeName(), structureRoot).isFinal())
{
return true;
}
else
{
return false;
}
}
public List<String> getSubAddressItems(String addressItem)
{
ArrayList<String> subAddressItems = new ArrayList<String>();
List<AddressNode> childNodes = getAddressNode(addressItem, structureRoot).getAllChilds();
for (int i = 0; i < childNodes.size(); i++)
{
subAddressItems.add(childNodes.get(i).getNodeName());
}
return subAddressItems;
}
private AddressNode getAddressNode(String nodeName, AddressNode root)
{
ArrayList<AddressNode> graphNodes = new ArrayList<AddressNode>();
ArrayList<AddressNode> passedNodes = new ArrayList<AddressNode>();
graphNodes.add(root);
while (graphNodes.size() != 0)
{
AddressNode cureNode = graphNodes.remove(0);
passedNodes.add(cureNode);
if (cureNode.getNodeName().equals(nodeName))
{
return cureNode;
}
else
{
for (int i = 0; i < cureNode.getAllChilds().size(); i++)
{
if (!passedNodes.contains(cureNode.getAllChilds().get(i)))
{
graphNodes.add(cureNode.getAllChilds().get(i));
}
}
}
}
return null;
}
private ArrayList<AddressNode> createRawNodes(TreeMap<String, ArrayList<String>> addressStructure)
{
int itemsSize = addressStructure.size();
ArrayList<AddressNode> tmpNodes = new ArrayList<AddressNode>();
ArrayList<AddressNode> finalNodes = new ArrayList<AddressNode>();
for (int i = 0; i < itemsSize; i++)
{
String curKey = addressStructure.firstKey();
ArrayList<String> curSubItems = addressStructure.remove(curKey);
AddressNode curNode = new AddressNode(curKey);
finalNodes.add(new AddressNode(curKey));
for (int j = 0; j < curSubItems.size(); j++)
{
curNode.addChlid(curSubItems.get(j));
}
tmpNodes.add(curNode);
}
for (int i = 0; i < finalNodes.size(); i++)
{
for (int j = 0; j < tmpNodes.get(i).getAllChilds().size(); j++)
{
AddressNode childNode = null;
boolean existNodeBefore = false;
for (int k = 0; k < finalNodes.size(); k++)
{
if (finalNodes.get(k).getNodeName().equals(tmpNodes.get(i).getAllChilds().get(j).getNodeName()))
{
childNode = finalNodes.get(k);
existNodeBefore = true;
}
}
if (!existNodeBefore)
{
finalNodes.get(i).addChlid(tmpNodes.get(i).getAllChilds().get(j).getNodeName());
}
else
{
finalNodes.get(i).addChildNode(childNode);
}
}
}
return finalNodes;
}
private void createTreeFromRawNodes(ArrayList<AddressNode> rawNodes, String rootName) throws StartAddressNodeNotFoundException
{
if (rootName == null)
{
throw new StartAddressNodeNotFoundException();
}
for (int i = 0; i < rawNodes.size(); i++)
{
if (rawNodes.get(i).getNodeName().equals(rootName))
{
structureRoot.addChildNode(rawNodes.get(i));
rawNodes.get(i).setParent(structureRoot);
}
}
}
public void addAddressItem(String itemName) throws AddressStructureAbusingException
{
AddressNode iterator = userRoot;
while (iterator.getAllChilds().size() > 0)
{
iterator = iterator.getAllChilds().get(0);
}
AddressNode fatherNode = getAddressNode(iterator.getNodeName(), structureRoot);
for (int i = 0; i < fatherNode.getAllChilds().size(); i++)
{
if (fatherNode.getAllChilds().get(i).getNodeName().equals(itemName))
{
iterator.addChlid(itemName);
return;
}
}
throw new AddressStructureAbusingException();
}
public void removeLastAddressItem() throws AddressNodeNotFoundException
{
if (userRoot.getAllChilds().size() > 0)
{
AddressNode iterator = userRoot;
while (iterator.getAllChilds().get(0).getAllChilds().size() > 0)
{
iterator = iterator.getAllChilds().get(0);
}
iterator.clearChilds();
}
else
{
throw new AddressNodeNotFoundException();
}
}
}
if it has to be broken how?
Your class has 230 lines - that's by no means excessive. However, size alone is only a very vague indicator of whether a class should be broken up.
A more general indicator is cohesion - basically, most of a class's methods should be using most of its fields. But that also isn't a problem in your class - it looks OK.
it has several responsibilites as I can see:
XML parsing (the representation)
XML manipulation (AddressNode)
hold parsing's output (the model)
at least I separate these two responsabilities in at least two separated classes.
NB
not concerned by the question there are also several empty catch blocks, see here why they are a bad idea
I've certainly seen bigger classes than that.
If you're finding it hard to read, I suggest strongly recommend putting some comments in there.
As long as your class revolves around a specific purpose, it should be as big as it needs to be to perform that purpose.
You may want to adapt
if (foo) {
bar();
} else {
fum();
}
instead. This allows the code to be shorter in length, allowing you to see more at once on the screen.
Also. Never have empty catch blocks. Consider "throw new RuntimeException("unexpected", e)" in them.