I'm currently writing a Tool in JavaFX.
Therefor I need to copy some columns from Microsoft Excel using cmd + c,
I then have the columns separated by tab in the clipboard.
e.g:
Column1 Column2 Column3
Value1 Value2 Value3
Value4 Value5 Value6
When I past the clipboard in an editor like Atom, they look exactly that way, but when I paste them into a TextArea, the line breaks are gone.
I need to do this, because I want to process the data from Excel using the Open CSV library.
Is there a way to keep the line breaks?
EDIT:
I just found out, if I use Clipboard.getSystemClipboard().getString() and than pass the String to my Open CSV handler, it works, but if I set the same string in a TextArea using textArea.setText(string) there are still no line breaks in the displayed Text.
Although it works now, I would like to user to paste the data into a TextArea, because it's a more common way than clicking a "paste&load" Button, and the user then also can check if all of the data was pasted.
I think the issue is that when Excel copies text to the System clipboard, it represents a line break as '\r', (ASCII 0xc) instead of the more standard '\n' (ASCII 0xa).
This is something of a hack, but if you do
TextArea textArea = new TextArea(){
#Override
public void replaceText(IndexRange range, String text) {
super.replaceText(range, text.replaceAll("\r", "\n"));
}
#Override
public void replaceText(int start, int end, String text) {
super.replaceText(start, end, text.replaceAll("\r", "\n"));
}
#Override
public void replaceSelection(String replacement) {
super.replaceSelection(replacement.replaceAll("\r", "\n"));
}
});
it will filter all the '\r' and replace them with '\n'.
Edit: here is a slightly cleaner version using a TextFormatter:
TextArea textArea = new TextArea();
UnaryOperator<Change> filter = c -> {
c.setText(c.getText().replaceAll("\r", "\n"));
return c ;
};
textField.setTextFormatter(new TextFormatter<>(filter));
Related
I have .csv file that has quoted values
Gender,ParentIncome,IQ,ParentEncouragement,CollegePlans
"Male",53900,118,"Encouraged","Plans to attend"
"Female",24900,87,"Not Encouraged","Does not plan to attend"
"Female",65800,93,"Not Encouraged","Does not plan to attend"
Reading this file with the following code (using IntelliJ and observing values in the debugger), returns values without quotes.
#Override
public CsvConnectorService read(String fullFileName, String outputAddress, int intervalMs, boolean repeat,
Handler<AsyncResult<Void>> result) {
CSVFormat format = CSVFormat.RFC4180.withHeader().withIgnoreEmptyLines().withQuote('"');
Subscription subscription = createCsvObservable(fullFileName, format, intervalMs, repeat)
.subscribeOn(Schedulers.io())
.subscribe(record ->
eventBus.publish(outputAddress, convertRecordToJson(record)));
subscriptions.add(subscription);
result.handle(Future.succeededFuture());
return this;
}
Reading with .withQuote('"'); or without it, makes no difference.
The quote " is the default character to represent quoted fields, and setting it explicitly makes no difference.
Do you want to get the original quote characters? In this case try setting the quote to a character that doesn't occur in the text, such as .withQuote('\0');
I am making a BE project "Data extraction using Natural Language processing". Here, the user needs to enter the query in English, which gets converted in SQL and fetches the data from database to the user.
I am using jframes in Netbeans 8.0.1.
Here, I take user input in Input.java and store it in varaible inp. On the basis of type of query I call the method Ans()/Place() and append the data in StringBuilder res. Finally, I use setText() method to display result in Output.java, in the textfield RES.
I want to modify the display of data in res, like making it little bold, append new content on new line, before it gets displayed in RES.
private void RunActionPerformed(java.awt.event.ActionEvent evt) {
Output n1 = new Output();
inp = this.TF_1.getText();
System.out.println("inp :" + inp);
String[] arr = inp.split(" ");
if ("Who".equals(arr[0])) {
res.append(Ans(arr[2]));
}
if ("Where".equals(arr[0])) {
res.append(Place(arr[2]));
}
Output.TF_value.setText(this.TF_1.getText());
Output.RES.setText(res.toString());
n1.setVisible(true);
}
I am working on CSV parser requirement and I am using supercsv parser library. My CSV file can have 25 columns(separated by tab(|)) and up to 100k rows with additional header row.
I would like to ignore white-space only lines and lines containing less than 25 columns.
I am using IcvBeanReader with name mappings(to set csv values to pojo) and field processors(to handle validations) for reading a file.
I am assuming that Supercsv IcvBeanReader will skip white space lines by default. But how to handle if a row contains less than 25 column numbers?
You can easily do this by writing your own Tokenizer.
For example, the following Tokenizer will have the same behaviour as the default one, but will skip over any lines that don't have the correct number of columns.
public class SkipBadColumnCountTokenizer extends Tokenizer {
private final int expectedColumns;
private final List<Integer> ignoredLines = new ArrayList<>();
public SkipBadColumnCountTokenizer(Reader reader,
CsvPreference preferences, int expectedColumns) {
super(reader, preferences);
this.expectedColumns = expectedColumns;
}
#Override
public boolean readColumns(List<String> columns) throws IOException {
boolean moreInputExists;
while ((moreInputExists = super.readColumns(columns)) &&
columns.size() != this.expectedColumns){
System.out.println(String.format("Ignoring line %s with %d columns: %s", getLineNumber(), columns.size(), getUntokenizedRow()));
ignoredLines.add(getLineNumber());
}
return moreInputExists;
}
public List<Integer> getIgnoredLines(){
return this.ignoredLines;
}
}
And a simple test using this Tokenizer...
#Test
public void testInvalidRows() throws IOException {
String input = "column1,column2,column3\n" +
"has,three,columns\n" +
"only,two\n" +
"one\n" +
"three,columns,again\n" +
"one,too,many,columns";
CsvPreference preference = CsvPreference.EXCEL_PREFERENCE;
int expectedColumns = 3;
SkipBadColumnCountTokenizer tokenizer = new SkipBadColumnCountTokenizer(
new StringReader(input), preference, expectedColumns);
try (ICsvBeanReader beanReader = new CsvBeanReader(tokenizer, preference)) {
String[] header = beanReader.getHeader(true);
TestBean bean;
while ((bean = beanReader.read(TestBean.class, header)) != null){
System.out.println(bean);
}
System.out.println(String.format("Ignored lines: %s", tokenizer.getIgnoredLines()));
}
}
Prints the following output (notice how it's skipped all of the invalid rows):
TestBean{column1='has', column2='three', column3='columns'}
Ignoring line 3 with 2 columns: only,two
Ignoring line 4 with 1 columns: one
TestBean{column1='three', column2='columns', column3='again'}
Ignoring line 6 with 4 columns: one,too,many,columns
Ignored lines: [3, 4, 6]
(1) If the selection must be done by your Java program using Super CSV, then (and I quote) "you'll have to use CsvListReader". In particular: listReader.length()
See this Super CSV page for details.
(2) If you can perform the selection by preprocessing the CSV file, then you might wish to consider a suitable command-line tool (or tools, depending on how complicated the CSV format is). If the delimiter of the CSV file does not occur within any field, then awk would suffice. For example, if the assumption is satisfied, and if the delimiter is |, then the relevant awk filter could be as simple as:
awk -F'|' 'NF == 25 {print}'
If the CSV file format is too complex for a naive application of awk, then you may wish to convert the complex format to a simpler one; often TSV has much to recommend it.
I have an SWT Text and i dont want any special characters to be entered , but only digits and numbers. So i have used the verify lister for the text :
text.addVerifyListener(new VerifyListener()
{
#Override
public void verifyText(VerifyEvent event)
{
char eachChar = (Character)event.character;
if(Character.isLetterOrDigit(eachChar))
{
event.doit = true;
}
else
{
event.doit = false;
}
}
});
So now i'll not be able to enter special characters.
1) How do i enable paste of a text inside the Text ?
2) And when i copy a text containing special characters from outside and paste it in the Text , it should not get pasted How do i restrict this ?
Please suggest me on this.
1) How do i enable paste of a text inside the Text ?
Paste will be enabled by default for SWT text. You no need to enable explicitly.
2) And when i copy a text containing special characters from outside and paste it in the Text , it should not get pasted How do i restrict this ?
"event.text" will give you the text you enter/paste to the SWT text. Validate this event.text with your regular expression (or with your isLetterOrDigit() by reading the event.text as character)
I was wondering if there is a way to keep the leading 0 while using SuperCsv.
My problem is that I have a few columns which have numbers with leading 0. I want to keep the 0, but excel keeps stripping it, I've also tried to append a few characters at the beginning of the number like ' = " but no good result.
Excel is displaying the first character which I've added at the beginning of the number, so the column value looks like =0222333111 , and that's because probably supercsv is wrapping the output between quotes.
I didn't find anything on the superCsv website and I guess I am not the only one who has this problem.
Should I migrate the to an Excel Java lib, or there is a workaround?
The CSV file format does not allow you to specify how the cells are treated by external programs. Even if the leading zeroes are written to the CSV file (please check that, if you have not already done so), Excel might think that it's smarter than you, that the leading zeroes are there by accident and discard them.
Even if there where some workarounds like adding all sorts of invisible Unicode characters, this is just a hack that is not guaranteed to work with other versions of Excel.
Therefore, CSV seems not to be an adequate file format for your requirements. Either switch to a different file format, or configure Excel to treat all cells as strings instead of numbers (I don't know how or if the latter is possible).
In supercsv, you can use custom cellprocessor below, it will append = in your cell value
public class PreserveLeadingZeroes extends CellProcessorAdaptor {
private static final Logger LOG = LoggerFactory.getLogger(PreserveLeadingZeroes.class);
public PreserveLeadingZeroes() {
super();
}
public PreserveLeadingZeroes(CellProcessor next) {
super(next);
}
public Object execute(Object value, CsvContext context) {
if (value == null) {
// LOG.debug("null customer code");
final String result = "";
return next.execute(result, context);
}
// LOG.debug("parse customer code : " + value.toString());
final String result = "=\"" + value.toString() + "\"";
return next.execute(result, context);
}
}