Posting from apple clipboard into JTable? - java

I would like to paste multiple cells from excel into JTable. Searching for the solution returned this old reference:
I used this ExcelAdapter.java with a couple of minor changes as I wanted it to work on Mac and not only on PC. So, I had to use that.
KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C,KeyEvent.META_DOWN_MASK);
When OS is Mac and also I found out that while copying, the new line character should be \r and not \n.
There is an interesting discussion on the subject
here.
So, now copying from JTable into excel works fine, but with pasting I have the following problem:
The starting cell where I want to paste gets active for editing once I press the Command Key, so when I press V the content from the clipboard does not write into that starting cell.
So, all other cells are filled fine, but not the first one. Here is the relevant snippets of the code.
public final static boolean SYSTEMISMAC=(System.getProperty("os.name")).startsWith("M");
....
if(SYSTEMISMAC) StringTokenizer st1=new StringTokenizer(trstring,"\r"); // For Mac
else StringTokenizer st1=new StringTokenizer(trstring,"\n");
for(int i=0;st1.hasMoreTokens();i++)
{
rowstring=st1.nextToken();
StringTokenizer st2=new StringTokenizer(rowstring,"\t");
for(int j=0;st2.hasMoreTokens();j++)
{
value=(String)st2.nextToken();
if (startRow+i< jTable1.getRowCount() &&
startCol+j< jTable1.getColumnCount())
jTable1.setValueAt(value,startRow+i,startCol+j);
System.out.println("Putting "+ value+" atrow= "+startRow+i+"column= "+startCol+j);
}
}
I can see that the program tries to get the value into the table when i=0 and j=0, but it cannot (I am guessing because the cell is already active). How to get over it?
Should I disable the activation of the cell by pressing Command (I don't think it is that useful, the user can use the mouse to select a cell, but how to disable)? I am not sure whether this problem is Mac specific (I have not checked Windows yet). If there is a better way of pasting from excel to JTable?

Just to summarize, as correctly pointed out by MadProgrammer, the key is to call Cell Editor and cancel any editing.
For completeness I am providing corrected snippet of the code with the corrections. It works for me
public final static boolean SYSTEMISMAC=(System.getProperty("os.name")).startsWith("M"); if(SYSTEMISMAC) StringTokenizer st1=new StringTokenizer(trstring,"\r"); // For Mac
else StringTokenizer st1=new StringTokenizer(trstring,"\n");
CellEditor cellEdit=jTable1.getCellEditor(startRow, startCol);
cellEdit.cancelCellEditing();
for(int i=0;st1.hasMoreTokens();i++)
{
rowstring=st1.nextToken();
StringTokenizer st2=new StringTokenizer(rowstring,"\t");
for(int j=0;st2.hasMoreTokens();j++)
{
value=(String)st2.nextToken();
if (startRow+i< jTable1.getRowCount() &&
startCol+j< jTable1.getColumnCount())
jTable1.setValueAt(value,startRow+i,startCol+j);
System.out.println("Putting "+ value+" atrow= "+startRow+i+"column= "+startCol+j);
}
}

I had better luck with this variant on your solution. By using both \n and \r as tokenisers on line 3 below I can paste from excel or from other sources like TextEdit.
The rowstring.replace on line 7 also allows me to carry over empty cells in a two-dimensional table from excel.
Keeping in mind that on Mac, I still have to copy and paste with control + C, control + P, not command + C, command + P
String trstring= (String)(system.getContents(this).getTransferData(DataFlavor.stringFlavor));
System.out.println("String is:"+trstring);
StringTokenizer st1=new StringTokenizer(trstring,"\n\r");
for(int i=0;st1.hasMoreTokens();i++)
{
rowstring=st1.nextToken();
rowstring = rowstring.replace("\t\t", "\t \t");
StringTokenizer st2=new StringTokenizer(rowstring,"\t");
for(int j=0;st2.hasMoreTokens();j++)
{
value=(String)st2.nextToken();
if (startRow+i< jTable1.getRowCount() &&
startCol+j< jTable1.getColumnCount())
jTable1.setValueAt(value,startRow+i,startCol+j);
System.out.println("Putting "+ value+"atrow="+startRow+i+"column="+startCol+j);
}
}

Related

Problems Formatting .CSV Output

I am currently programming an assignment for a class of mine. I am trying to print to my output file to a csv file. The problem is, after I end my second print statement, my output doesn't line up after starting the print statement in my while loop.
For example, here is my code:
oFile = new PrintStream(new File("output.csv"));
oFile.println("First Name" + "," + "Last Name" + "," + "Lecture Section"+","+"Lab Section"+","+"Lab 1"+","+"Lab 2"+","+"Lab 3"+","+"Lab 4"+","+"Lab 5"+","+"Lab 6"+","+"Lab 7"+","+"Lab 8"+","+"Lab 9"+","+"Lab 10");
loadLectureArray();
loadLabArray();
sortClassSections();
for (int i = 0; i < stud.size(); i++) {
oFile.println(stud.get(i).getStudFirstName() + ","+stud.get(i).getStudLastName()+","+stud.get(i).getStudLectureNum()+","+stud.get(i).getStudLabNum()+",");
while (numLab < 10 && i < stud.size()) {
oFile.println(labStud.get(i).grades.getStudLabGrade()[numLab]);
numLab++;
}
numLab = 0;
}
After I execute my while loop, my new data is printed in-between my header and other data. Some of the code is not perfect, but currently I am just seeking advice about reformatting my output to line back up with the print statements.
This is my first time exporting a file to csv, so if there is something I am doing wrong or need to change, please let me know! I hope you can make sense out of what I'm trying to ask for. Thanks in advance!
well, println always prints a newline, so you get a newline after every grade. you should be able to get what you want using oFile.print(...) instead of oFile.println(...) inside the for loop and just one oFile.println() at the very end of it.
i also noticed that the test for i < stud.size() in the head of the while loop is redundant since nothing should be changing either i or stud.size() between this test and the same test in the head of the for loop.

JavaFX splitting Clipboard getString() strange behavior

I made a program using JavaFX where I have to paste into an excel like table.
I followed some tutorials online but noticed strange behavior in the way the paste code functions. After a while, I isolated the problem to the following code.
public void handlePaste() {
Clipboard clipboard = Clipboard.getSystemClipboard();
if (clipboard.hasString()) {
//start from the point that has focus
// abort if there's not cell selected to start with
if (getSelectionModel().getSelectedCells().size() == 0) {
return;
}
// get the cell position to start with
TablePosition pasteCellPosition = getFocusModel().getFocusedCell();
String pasteString = Clipboard.getSystemClipboard().getString();
int rowClipboard = -1;
Iterable<String> rowStrings = Splitter.on("\n").omitEmptyStrings().split(pasteString);
System.out.println("Print Rows");
for (String rowString : rowStrings) {
System.out.println(rowString);
System.out.println(rowString + " printing again");
}
for (String rowString : rowStrings) {
rowClipboard++;
Iterable<String> columnStrings = Splitter.on("\t").split(rowString);
int colClipboard = -1;
System.out.println("Printing Columns");
for (String columnString : columnStrings) {
System.out.println(columnString);
System.out.println(columnString + " printing again");
}
}
}
}
I use the output statement to demonstrate the problem.
Basically, I'm splitting the contents of the string based off and '\n' and '\t' characters.
The problem is whenever I try to do anything with the split strings, the string just...DISAPPEARS...
The output statements I put in demonstrate this.
Suppose the string on the clipboard is
l a
l b
l c
Then the expected output should be
Print rows
l a
l a printing again
l b
l b printing again
r c
r c printing again
Printing Columns
l
l again
a
a again
l
l again
b
b again
r
r again
c
c again
But the output ends up being
Print rows
l a
printing again
l b
printing again
r c
printing again
Printing Columns
l
again
a
again
l
again
b
again
r
again
c
again
Notice how when I try to append " printing again" to the split string, I'm simply getting blank strings.
I tried fixing the issue by using substring, and by using the standard java string splitting methods and I got the same behavior.
Finally, to fix it, I just used the java.awt Clipboard instead of the JavaFX clipboard and suddenly...it worked!
java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
java.awt.datatransfer.Clipboard awtClipboard = toolkit.getSystemClipboard();
try {
pasteString = (String) awtClipboard.getData(java.awt.datatransfer.DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException ex) {
} catch (IOException ex) {
}
Using the above line of code to get the pasteString instead of the JavaFX clipboard fixed the problem, and now I get the expected behavior and output.
For now, I will stick with the above fix, but it seems strange that the JavaFX clipboard is producing this behavior when the awt clipboard does not. Can anybody explain why this is happening? Is this a bug with the JavaFX clipboard?
LuxxMiner's comment above appears to offer a solution.
Using System.lineSeparator() also seems to work fine.
Unfortunately I found the above solutions didn't quite work out for me. The problem is that while the system seperator does get me the seperator for my systems, when I copy and paste from another program, it isn't guaranteed that the program I'm copying from is using the systems' seperator. For instance, when I copied from an excel spreadsheet, I kept getting the same strange behavior I got before, and I believe it was because excel didn't use the systems seperator.
So this is the solution I eventually came upon...
Basically it looks for ANY of the basic line seperators and splits on them.
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
Iterable<String> rowStrings = Splitter.on(CharMatcher.anyOf("\n\r")).omitEmptyStrings().split(pasteString);

How to print an array list (that's using char) in a JTextArea?

Okay, so I have to make a game for school that's called "Angry Tanks" it's basically a simpler version of Angry Birds.
We have to read in a textfile to use as a landscape for our game, this text file contais spaces and hashtags, the hastags represent the land.
The file has bean read and inserted into an arraylist, there is a public method calles getLandscapeFromFile().
I am trying to print the landscape into a JTextArea called textArea, using a loop that replaces all the hashtags with an image. Am I supposed to use a textArea or should another panel be used?
This is the code I've tried but doesn't work:
for (int i = 0; i < Landscape.getLandscapeFromFile().size(); i++) {
for (char[] c : Landscape.getLandscapeFromFile()) {
textArea.append(String.valueOf(c[i]));
}
}
I've been trying all sort of stuff, but nothing seems to work...
And by the way, I'm not very good at Java, this is only my first year studying IT.
The problem is in your second loop
You select i char of word
for (char[] c : Landscape.getLandscapeFromFile()) {
textArea.append(String.valueOf(c[i]));
}
You probably wonted to write each character of that array.
for (char[] c : Landscape.getLandscapeFromFile()) {
textArea.append(String.valueOf(c));
}
As you task is to write the content form File to textArea you should do this.
TIP: You should avoid to access the loading method twice as it can time consuming user a local variable.
List<char[]> landscapes = Landscape.getLandscapeFromFile(); //Read once
for(char[] landscape : landscapes) {//Iterate through all landscapes
stextArea.append(new String(landscape)); //Create new String for char array
}
You can use a StringBuilder:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Landscape.getLandscapeFromFile().size(); i++) {
for (char[] c : Landscape.getLandscapeFromFile()) {
sb.append(String.valueOf(c));
}
}
textArea.setText(sb.toString());

String Input (Only outputs the first word said)

I'm trying to make a piece of code that will yell out anything I input.
So the command is 'yell'
I want to be able to type 'yell (whatever i want here)' and it will yell it out. I've managed to get this working with a help of a friend. But for some reason it will only yell the first word that's been output. So I can't type a sentence because it will only say the first word of a sentence.
Here's the piece of code, I hope you can help.
case "npcyell":
for (NPC n : World.getNPCs()) {
if (n != null && Utils.getDistance(player, n) < 9) {
String sentence = "";
for (int i = 1; i < cmd.length; i++) {
sentence = sentence + " " + cmd[i];
}
n.setNextForceTalk(new ForceTalk("[Alert] "
+ Utils.getFormatedMessage(sentence)));
}
}
return true;
Well I did something similar a while ago. You said that you wanted to be able to say "yell(text)" and have it output whatever the text was. I have a different way of implementing it than you do, but the general result is the same, but it can be adapted to however you are using it in this context. This is also assuming that you are running this program as a console project only. if not change the scanner with whatever you are using to input text into and replace the text assignment to text = textInputArea.getText().toString(); and change the output statement to System.out.println(text.getText().toString().substring(6,text.getText().toString().length() - 1));
Scanner s = new Scanner(System.in);
String text = s.nextLine();
if (text.startsWith("yell(") && text.endsWith(")")){
System.out.println(text.substring(6,text.length() - 1));
}
I hope this works for you. And I honestly hope that this is adaptable towards the program you are making.

How can I make the display of a line in my command-line java program change without displaying a new line?

I'm making a java command line program.
How can I change the contents of a line I've already displayed?
So, for example I could display:
Status: 0%
Status: 2%
...
Status: 50%
Except, rather than continuing to push down each new line, I simply change the contents of the existing line, so the % done changes in place.
I've seen some console programs do this before, so how can I do it in java?
In most cases, you can output a carriage return (\r) rather than a newline (\n). This depends on the terminal supporting it, which most do. \r moves the cursor back to the beginning of the line.
EDIT: Obviously, when doing this, use System.out.print rather than System.out.println (or just generally use the plain, not ln, form of the output method you're using) -- since the ln suffix means that your text is automatically followed with a newline.
Example:
for (n = 10000; n < 10010; ++n) {
System.out.print(String.valueOf(n) + "\r");
}
System.out.println("Done");
When this finishes, you'll probably have this on your console screen:
Done0
...since "Done" is shorter than the longest previous thing you output, and so didn't completely overwrite it (hence the 0 at the end, left over from "10010"). So the lesson is: Keep track of the longest thing you write and overwrite it with spaces.
Take a look at this example.
Working code:
public class progress {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i <= 100; i++) {
Thread.sleep(30);
System.out.print("\rSTATUS: "+i+" % " );
}
}
}
Tip: For more Google - java console progress bar

Categories

Resources