Load database Field Values to A JCombobox - java

How to load values from an Oracle db to a JComboBox to make it easier for the user To Choose from I Have tried this:
Connection dbcon = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
dbcon = DriverManager.getConnection("
jdbc:oracle:thin:#localhost:1521:XE", "USERNAME", "PASSWORD");
Statement st = dbcon.createStatement();
String combo = "Select EMP_IDNUM from employees";
ResultSet res = st.executeQuery(combo);
while(res.next()){
String ids = res.getString("EMP_IDNUM");
String [] str = new String[]{ids};
cboId = new JComboBox(str);
}
} catch (Exception d) {
System.out.println(d);
}
This is Only getting me the first Value Into the JComboBox cboID. What Is the Best way to Load the entire Field Data (EMP_IDNUM) into the Jcombobox??

String [] str = new String[]{ids};
It means your String array is having only one ids value which you have loaded String ids = res.getString("EMP_IDNUM");
if(rs.getRow()>0){
String [] str = new String[res.getRow()];
int i=0;
while(res.next()){
str[i++] = res.getString("EMP_IDNUM");
}
}
JComboBox jcb = new JComboBox(str);
Instead of array you can use Vector also to create JComboBox.

you can use this code:
Vector v = new Vector();
while(res.next()){
String ids = res.getString("EMP_IDNUM");
v.add(ids)
}
JComboBox jcb = new JComboBox(v);
In this code you create a Vector with your Strings, and then invoke directly the JComboBox(Vector items) constructor of JComboBox

there are three important areas
a) close all JDBC Objects in the finally block, because these Object aren't, never GC'ed
try {
} catch (Exception d) {
System.out.println(d);
} finally {
try {
st.close()
res.close()
dbcon.close()
} catch (Exception d) {
//not important
}
}
b) don't to create any Objects inside try - catch - finally, prepare that before
meaning cboId = new JComboBox(str);
c) put all data from JDBC to the ComboBoxModel, prepare that before

Related

how to get arraylist values one by one and put it in stringbuilder java?

all,
I have an arraylist and I want to take the values one by one and put them in the string builder.
I have tried several steps, such as looping for and foreach
this is my code :
try{
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/"+jComboBox1.getSelectedItem()+"","root","");
Statement stmt=con.createStatement();
for(int i =0; i < box.size();i++){
if(box.get(i).isSelected()){
//System.out.print(box.get(i).getText().trim());
ResultSet rs=stmt.executeQuery("select "+box.get(i).getText().trim()+" from "+jComboBox3.getSelectedItem()+";");
while(rs.next()){
isikolom = rs.getString(1);
isi.add(isikolom);
String getkey = jTextField1.getText().toString();
byte[] key = getkey.getBytes();
RC4 rc = new RC4(new String(key));
byte[] desText = rc.decrypt(enText);
descrypted = new String(desText);
StringBuilder sb2 = new StringBuilder(128);
sb2.append("UPDATE ").append(jComboBox3.getSelectedItem().toString()).append(" SET ");
sb2.append(box.get(i).getText().toString()+" = ").append("REPLACE ").append("("+box.get(i).getText().toString()+",");
sb2.append("'"+isikolom+"'").append(",");
isideskripsi.stream().forEach(isideskripsi -> {
sb2.append("'"+isideskripsi+"'");
});
sb2.append(")");
String query2 = sb2.toString();
System.out.println(query2);
PreparedStatement presatet2 = con.prepareStatement(query2);
// presatet2.executeUpdate();
}
System.out.println("After Encryption : "+isiencrypsi);
System.out.println("After Descryption : "+isideskripsi);
}
}
end = System.currentTimeMillis();
long time = end - start;
JOptionPane.showMessageDialog(null, "Berhasil Deskripsi Dalam Waktu "+time+" Detik");
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Gagal Deskripsi, Error Pada : "+e);
System.out.print(e);
}
arraylist items is [admin, pegawai, penyidik]
this is result of that code :
UPDATE user SET username = REPLACE (username,'X"mBR','admin''pegawai''penyidik')
UPDATE user SET username = REPLACE (username,'I#gJK�','admin''pegawai''penyidik')
UPDATE user SET username = REPLACE (username,' I#nRU� �','admin''pegawai''penyidik')
the results i expected :
UPDATE user SET username = REPLACE (username,'X"mBR','admin')
UPDATE user SET username = REPLACE (username,'I#gJK�','pegawai')
UPDATE user SET username = REPLACE (username,' I#nRU� �','penyidik')
Because your description is not clear, I am not sure what you want to do is as follows:
int idx = 0;
while(rs.next()) {
...
sb2.append("'"+isikolom+"'").append(",");
/* remove this block
isideskripsi.stream().forEach(isideskripsi -> {
sb2.append("'"+isideskripsi+"'");
});
*/
sb2.append("'").append(isideskripsi.get(idx)).append("'");
sb2.append(")");
idx++;
...
}
isideskripsi.stream().forEach(isideskripsi -> {
sb2.append("'"+isideskripsi+"'");
});
The above code problems, because every time you build your SQL, you output all the items inside the arraylist, instead you should:
sb2.append("'"+isideskripsi.get(i-1)+"'");
As you only want every one arraylist item one time

Make custom code to reduce number of repetitive lines

I have to get 'tags' from the database and store them in an array so I could check if my document contains them. Due to the number of tag categories (customers, system_dependencies, keywords) I have multiple arrays to compare my document with. Is there an easy way to simplify and make my code look nicer?
This is my approach but it looks terrible with all the repetitive for loops.
ArrayList<String> KEYWORDS2 = new ArrayList<String>();
ArrayList<String> CUSTOMERS = new ArrayList<String>();
ArrayList<String> SYSTEM_DEPS = new ArrayList<String>();
ArrayList<String> MODULES = new ArrayList<String>();
ArrayList<String> DRIVE_DEFS = new ArrayList<String>();
ArrayList<String> PROCESS_IDS = new ArrayList<String>();
while (resultSet2.next()) {
CUSTOMERS.add(resultSet2.getString(1));
}
sql = "SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = 6";
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
while (resultSet2.next()) {
SYSTEM_DEPS.add(resultSet2.getString(1));
}
while (resultSet.next()) {
String da_document_id = resultSet.getString(1);
String file_name = resultSet.getString(2);
try {
if(file_name.endsWith(".docx") || file_name.endsWith(".docm")) {
System.out.println(file_name);
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
//Return what's inside the document
System.out.println("Keywords found in the document:");
for (String keyword : KEYWORDS) {
if (wordExtractor.getText().contains(keyword)) {
System.out.println(keyword);
}
}
System.out.println("\nCustomers found in the document:");
for (String customer : CUSTOMERS) {
if (wordExtractor.getText().contains(customer)) {
System.out.println(customer);
}
}
System.out.println("\nSystem dependencies found in the document:");
for (String systemDeps : SYSTEM_DEPS) {
if (wordExtractor.getText().contains(systemDeps)) {
System.out.println(systemDeps);
}
}
System.out.println("Log number: " + findLogNumber(wordExtractor));
System.out.println("------------------------------------------");
wordExtractor.close();
}
As you can see there are 3 more to come and this doesn't look good already. Maybe there's a way to compare all of them at the same time.
I have made another attempt at this creating this method:
public void genericForEachLoop(ArrayList<String> al, POITextExtractor te) {
for (String item : al) {
if (te.getText().contains(item)) {
System.out.println(item);
}
}
}
Then calling it like so: genericForEachLoop(MODULES, wordExtractor);
Any better solutions?
I've got two ideas to shorten this: first of all you can write a general for-loop in a separate method that has an ArrayList as a parameter. Then you pass it each of your ArrayLists successively, which would mean that at least you do not have to repeat the for-loops. Secondly, you can create an ArrayList of type ArrayList and store your ArrayLists inside it. Then you can iterate over the whole thing. Only apparent disadvantage of both ideas (or a combination of them) would be, that you need to name the variable for your query string alike for the search of each ArrayList.
What you could do is use a Map and an enum like this:
enum TagType {
KEYWORDS2(2), // or whatever its da_tag_type_id is
CUSTOMERS(4),
SYSTEM_DEPS(6),
MODULES(8),
DRIVE_DEFS(10),
PROCESS_IDS(12);
public final daTagTypeId; // this will be used in queries
TagType(int daTagTypeId) {
this.daTagTypeId = daTagTypeId;
}
}
Map<TagType, List<String>> tags = new HashMap<>();
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
for(TagType tagType : TagType.values()) {
tags.put(tagType, new ArrayList<>()); // initialize
String sql = String.format("SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = %d", tagType.daTagTypeId); // build query
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
while(resultSet2.next()) { // fill from DB
tags.get(tagType).add(.add(resultSet2.getString(1)));
}
System.out.println(String.format("%s found in the document:", tags.get(tagType).name());
for (String tag : tags.get(tagType)) { // search in text
if (wordExtractor.getText().contains(tag)) {
System.out.println(keyword);
}
}
}
But at this point I'm not sure you need those lists at all:
enum TagType {
KEYWORDS2(2), // or whatever its da_tag_type_id is
CUSTOMERS(4),
SYSTEM_DEPS(6),
MODULES(8),
DRIVE_DEFS(10),
PROCESS_IDS(12);
public final daTagTypeId; // this will be used in queries
TagType(int daTagTypeId) {
this.daTagTypeId = daTagTypeId;
}
}
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
for(TagType tagType : TagType.values()) {
String sql = String.format("SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = %d", tagType.daTagTypeId); // build query
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
System.out.println(String.format("%s found in the document:", tags.get(tagType).name());
while(result2.next()) {
String tag = resultSet2.getString(1);
if (wordExtractor.getText().contains(tag)) {
System.out.println(keyword);
}
}
}
This given I don't know where those resultSet is declared and initialised, nor where that resultSet2 is initialised.
Basically you just fetch tags for each type from DB and then directly search them in the text without storing them at first and then re-iterating the stored ones... I mean that's what the DB is there for.

CommandTable Cystal Report Error

I have a Crystal Report that was written using a complex SQL and I'm trying to invoke that using the Crystal Report Java API. This report has a Command object associated with it.
I load the report and set the connection parameters.
Then I try to set the Connection information to the current JDBC Profile. Meaning Test Environment credentials.
I get an exception. I tried with Version 11. Version 12 both. None of them seems to be working.
I'm getting the exception when I invoke the following piece of code. This piece of code works just fine with reports without "Command" sqls.
try{
clientDoc.getDatabaseController().setTableLocation(
origTable, newTable);
}catch(Exception ex){
ex.printStackTrace();
}
See below for the entire code. Please reply if anyone knows how to work around this.
private static void changeDataSource(ReportClientDocument clientDoc,
String reportName, String tableName, String username,
String password, String connectionURL, String driverName,
String jndiName) throws ReportSDKException {
PropertyBag propertyBag = null;
IConnectionInfo connectionInfo = null;
ITable origTable = null;
ITable newTable = null;
// Declare variables to hold ConnectionInfo values.
// Below is the list of values required to switch to use a JDBC/JNDI
// connection
String TRUSTED_CONNECTION = "false";
String SERVER_TYPE = "JDBC (JNDI)";
String USE_JDBC = "true";
String DATABASE_DLL = "crdb_jdbc.dll";
String JNDI_OPTIONAL_NAME = jndiName;
String CONNECTION_URL = connectionURL;
String DATABASE_CLASS_NAME = driverName;
// Declare variables to hold database User Name and Password values
String DB_USER_NAME = username;
String DB_PASSWORD = password;
System.out.println("Trusted_Connection:" + TRUSTED_CONNECTION);
System.out.println("Server Type:" + SERVER_TYPE);
System.out.println("Use JDBC:" + USE_JDBC);
System.out.println("Database DLL:" + DATABASE_DLL);
System.out.println("JNDIOptionalName:" + JNDI_OPTIONAL_NAME);
System.out.println("Connection URL:" + CONNECTION_URL);
System.out.println("Database Class Name:" + DATABASE_CLASS_NAME);
System.out.println("DB_USER_NAME:" + DB_USER_NAME);
System.out.println("DB_PASSWORD:" + DB_PASSWORD);
// Obtain collection of tables from this database controller
if (reportName == null || reportName.equals("")) {
Tables tables = clientDoc.getDatabaseController().getDatabase()
.getTables();
for (int i = 0; i < tables.size(); i++) {
origTable = tables.getTable(i);
if (tableName == null || origTable.getName().equals(tableName)) {
newTable = (ITable) origTable;
newTable.setQualifiedName(origTable.getAlias());
connectionInfo = newTable.getConnectionInfo();
// Set new table connection property attributes
propertyBag = new PropertyBag();
// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL", DATABASE_DLL);
propertyBag.put("JNDIOptionalName", JNDI_OPTIONAL_NAME);
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);
connectionInfo.setAttributes(propertyBag);
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);
// Update the table information
try{
clientDoc.getDatabaseController().setTableLocation(
origTable, newTable);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
// Next loop through all the subreports and pass in the same
// information. You may consider
// creating a separate method which accepts
if (reportName == null || !(reportName.equals(""))) {
IStrings subNames = clientDoc.getSubreportController()
.getSubreportNames();
for (int subNum = 0; subNum < subNames.size(); subNum++) {
Tables tables = clientDoc.getSubreportController()
.getSubreport(subNames.getString(subNum))
.getDatabaseController().getDatabase().getTables();
for (int i = 0; i < tables.size(); i++) {
origTable = tables.getTable(i);
if (tableName == null
|| origTable.getName().equals(tableName)) {
newTable = (ITable) origTable;
newTable.setQualifiedName(origTable.getAlias());
// Change connection information properties
connectionInfo = newTable.getConnectionInfo();
// Set new table connection property attributes
propertyBag = new PropertyBag();
// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection",
TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL", DATABASE_DLL);
propertyBag.put("JNDIOptionalName", JNDI_OPTIONAL_NAME);
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name",
DATABASE_CLASS_NAME);
connectionInfo.setAttributes(propertyBag);
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);
// Update the table information
clientDoc.getSubreportController()
.getSubreport(subNames.getString(subNum))
.getDatabaseController()
.setTableLocation(origTable, newTable);
}
}
}
}
}
Add after this line of yours
connectionInfo.setPassword(DB_PASSWORD);
newTable.setConnectionInfo(connectionInfo);
//This will add connection parameters to the new table
Instead of
clientDoc.getDatabaseController().setTableLocation(origTable, newTable);
replace this with
clientDoc.getDatabaseController ().setTableLocation (newTable, tables.getTable(i));

Write Java Vector To Delimited File

I am connecting to an Oracle database and querying multiple tables. My current code creates the connection and calls a PL/SQL function which contains the query. Once I have the result set, I add it to a Vector (as I am unsure the number of records each query will result in).
My problem is that I am unsure how to write a delimited file from the Vector. I imagine once I have added my result set to it, it is simply one gigantic string. I need to be able to receive each field from the query and delimit between them, as well as keep rows separate.
Here is my code:
public static void main(String[] args) throws SQLException {
// instantiate db connection
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}catch (Exception e) {
throw new SQLException("Oracle JDBC is not available", e);
}
// define connection string and parameters
String url = "jdbc:oracle:thin:#//host:port/sid";
Connection conn = DriverManager.getConnection(url, "USERNAME","PASSWORD");
CallableStatement stmt = conn.prepareCall("{? = CALL <functionname>(?)}");
// get result set and add to a Vector
ResultSet rs = stmt.executeQuery();
Vector<String> results = new Vector();
while ( rs.next() ){
results.add(rs.getString(1));
}
// close result set, sql statement, and connection
rs.close();
stmt.close();
conn.close();
// write Vector to output file,
// where the file name format is MMddyyyy.txt
try {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MMddyyyy");
String dateStr = sdf.format(cal.getTime());
FileWriter fwrite = new FileWriter(dateStr + ".txt");
BufferedWriter out = new BufferedWriter(fwrite);
for(int i = 0; i < results.size(); i++)
{
String temp = results.elementAt(i);
out.write(temp);
}
out.close();
}catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
I am just unsure how to go about getting the information from the db and writing it to a delimited file. Thanks in advance!
If you are unsure about the number of fields in each of your rows, then probably, it won't be possible. Because to fetch all the field values from database, you need to know what is the type of each fields, and the number of fields.
But, I'll post an example for when you have fixed number of fields, that you know.
Suppose you have 4 columns per row. Now to display it in tabular form, you would have to use List of List.
If you are using Vector, use Vector of List.
Here's an example for List of List: -
List<List<String>> results = new ArrayList<List<String>>();
while ( rs.next() ) {
List<String> tempList = new ArrayList<String>();
tempList.add(rs.getString(1));
tempList.add(rs.getString(2));
tempList.add(rs.getString(3));
tempList.add(rs.getString(4));
results.add(tempList);
}
Then to print it, use this loop: -
for (List<String> innerList: results) {
for (String fields: innerList) {
System.out.print(fields + "\t");
}
System.out.println();
}
You can write it in the same form to your BufferedWriter.
Use results.toString() and truncate the braces([]) from resulting string to write all values as comma separated at once in the file.
//toString() returns comma separated string values enclosed in []
String resultString = results.toString();
//truncate leading '[' and termincating ']'
resultString = resultString.substring(1, resultString.length()-1);
//if comma is not your delimiter then use String.replaceAll()
//to replace `,` with your delimiter
//write comma separated elements all at once
out.write(resultString);
So here if you have added str1, str2 in the results Vector, then resultString with have value as str1, str2, which you may write at once using your BufferedWriter out.
Also please use Generics in both the sides of initialization as:
Vector<String> results = new Vector<String>();

replaceAll() method using parameter from text file

i have a collection of raw text in a table in database, i need to replace some words in this collection using a set of words.
i put all the term to be replace and its substitutes in a text file as below
min=admin
lelet=lambat
lemot=lambat
nii=nih
ntu=itu
and so on.
i have successfully initiate a variabel of File and Scanner to read the collection of the term and its substitutes.
i loop all the dataset and save the raw text in a string
in the same loop
i loop all the term collection and save its row to a string name 'pattern', and split the pattern into two string named 'term' and 'replacer'
in this loop i initiate a new string which its value is the string from the dataset modified by replaceAll(term,replacer)
end loop for term collection
then i insert the new string to another table in database
end loop for dataset
i do it manualy as below
replaceAll("min","admin")
and its works but its really something to code it manually for almost 2000 terms to be replace it.
anyone ever face this kind of really something..
i really need a help now desperate :(
package sentimenrepo;
import javax.swing.*;
import java.sql.*;
import java.io.*;
//import java.util.HashMap;
import java.util.Scanner;
//import java.util.Map;
/**
*
* #author herman
*/
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet");
ResultSet RS = select.getResultSet();
Scanner scSynV2 = new Scanner(synonimV2);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
clean2 cleanv2 = new clean2();
newTweet = cleanv2.cleanTweet(tweet);
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+newTweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
return row;
}
class clean2{
public clean2(){}
public String cleanTweet(String tweet){
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String pattern = "";
String term = "";
String replacer = "";
String newTweet="";
try{
Scanner scSynV2 = new Scanner(synonimV2);
while(scSynV2.hasNext()){
pattern = scSynV2.next();
term = pattern.split("=")[0];
replacer = pattern.split("=")[1];
newTweet = tweet.replace(term, replacer);
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println(newTweet+"\n"+tweet);
return newTweet;
}
}
}
update
ive just realize that the code actually works but only for the first row in database, the second row and so on stand still. here is i update the newest code i ve build
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
Opening the synonym file and iterating over 2,000 lines for every row in your ResultSet is a bit wasteful.
Load your synonyms into an in-memory Map once, keyed by unique misspelt term, then do a lookup on the map for every row in your result set, and replace as necessary.
Let us use both solutions to build a single solution for you:
First, you create a HashMap with all your keys:
public static HashMap<String, String> getMap() {
//your version would read from the file
HashMap<String,String> myMap=new HashMap<String,String>();
myMap.put("min", "admin");
myMap.put("lelet", "lambat");
myMap.put("lemot", "lambat");
myMap.put("nii", "nih");
myMap.put("ntu", "itu");
return(myMap);
}
Second, you create a pattern that contains all the keys in your hashmap:
public static String getPattern(HashMap<String,String> mapReplacement) {
String pattern="";
for (String s : mapReplacement.keySet()) {
if (!pattern.isEmpty()) {
pattern=pattern+"|";
}
pattern=pattern+s;
}
return(pattern);
}
Next, you can create a cleanTweet method that uses both structures you created:
public static String cleanTweet(String tweet, Pattern pattern,HashMap<String, String> myMap) {
String newTweet=tweet;
Matcher matcher = pattern.matcher(newTweet);
int start=0;
while (matcher.find()) {
String key=matcher.group();
String replacement=myMap.get(key);
if (replacement!=null) {
newTweet=newTweet.replace(key, replacement );
}
}
return(newTweet);
}
This might require some tweaking to perfect (I onyl tested a few cases), but the point is that you are going to iterate a single time in your keys and then iterate only on your tweets.
I hope it helps.
I didn't try, but it seems to me that you've almost got it - just replace this line:
newTweet = tweet.replace(term, replacer);
with this:
tweet = tweet.replaceAll(term, replacer);
As you're not using newTweet any more, return tweet:
return tweet;
You should also delete the newTweet declaration.
Also, you shouldn't read Scanner to read lines. Use FileReader instead.
thanks folks
i ve found the answer why the code is not working,
the txt file containing terms and its substitutes should be initiated each time the program read a row from database.
the code would be like this
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
while(RS.next()){
row++;
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
but im actually want to apply the code in which rlinden made above, but cant figure it out how to call the cleanTweet function.

Categories