i have a problem with this exception.
I'm trying to make a function to display data from database on a table, every keystroke i made at jtextfield. So its like the table automatically refreshed with new data everytime i type in the jtextfield.
Here's the code :
First i have this variable :
private Statement stmt;
List<Barang> dataSBarang =new LinkedList();
boolean searchBarang=true;
Searching sBarang;
And this is how i call the function :
private void inputkodeTFMouseClicked(java.awt.event.MouseEvent evt){
sBarang = new Searching( stmt, dataSBarang, modelDetail, tabelDetailBarang, inputkodeTF, searchBarang);
sBarang.start();
}
And this is the Searching Object
public class Searching extends Thread{
private Statement stmt;
private List<Barang> dataBarang;
private JTable jTabelBarang;
private JTextField tf;
private boolean cari;
private DefaultTableModel modelBarang;
public Searching(Statement stmt, List<Barang> dataBarang, DefaultTableModel tm, JTable jTabelBarang, JTextField tf, boolean cari){
this.stmt=stmt;
this.dataBarang=dataBarang;
this.modelBarang=tm;
this.jTabelBarang=jTabelBarang;
this.tf=tf;
this.cari=cari;
}
#Override
public void run(){
String temp="";
while(cari==true){
//System.out.println("jalan");
try{
String masukan = tf.getText();
System.out.println(masukan);
if(!masukan.equals("")&&!masukan.equals(temp)){
clearTableBarang();
//System.out.println("Mencari "+ masukan);
ResultSet rs = stmt.executeQuery("select kode_barang, nama_barang, jumlah_stok, " +
"minimal_stok, harga_jual, deskripsi_barang from BARANG WHERE (kode_barang LIKE " +
"'"+masukan+"%')");
System.out.println(rs);
while(rs.next()){
String kode_barang = rs.getString ("kode_barang");
String nama_barang = rs.getString ("nama_barang");
int jumlah_stok = rs.getInt("jumlah_stok");
int minimal_stok = rs.getInt("minimal_stok");
int harga_jual = rs.getInt("harga_jual");
String deskripsi_barang = rs.getString ("deskripsi_barang");
//System.out.println(kode_barang+" "+deskripsi_barang);
dataBarang.add(new Barang(kode_barang,nama_barang,jumlah_stok,minimal_stok,harga_jual,deskripsi_barang));
((DefaultTableModel) jTabelBarang.getModel()).insertRow(jTabelBarang.getRowCount(), new Object[]{kode_barang, nama_barang, jumlah_stok, minimal_stok, harga_jual, deskripsi_barang});
}
temp = masukan;
}
else if(masukan.equals("")&&!masukan.equals(temp)) {
clearTableBarang();
showTableBarang();
temp = masukan;
}
} catch(SQLException s){s.printStackTrace();}
catch(ArrayIndexOutOfBoundsException s){s.printStackTrace();}
try {
sleep(500);
} catch(InterruptedException e){}
}
}
public void clearTableBarang(){
int numrows = modelBarang.getRowCount();
for(int i = numrows - 1; i >=0; i--){
modelBarang.removeRow(i);
}
dataBarang.clear();
}
public void showTableBarang(){
try{
ResultSet rs = stmt.executeQuery("select kode_barang, nama_barang, jumlah_stok, minimal_stok, harga_jual, deskripsi_barang from barang");
while(rs.next()){
String kode_barang = rs.getString ("kode_barang");
String nama_barang = rs.getString ("nama_barang");
int jumlah_stok = rs.getInt("jumlah_stok");
int minimal_stok = rs.getInt("minimal_stok");
int harga_jual = rs.getInt("harga_jual");
String deskripsi_barang = rs.getString ("deskripsi_barang");
//System.out.println(kode_barang+" "+deskripsi_barang);
dataBarang.add(new Barang(kode_barang,nama_barang,jumlah_stok,minimal_stok,harga_jual,deskripsi_barang));
((DefaultTableModel)jTabelBarang.getModel()).insertRow(jTabelBarang.getRowCount(), new Object[]{kode_barang, nama_barang, jumlah_stok, minimal_stok, harga_jual, deskripsi_barang});
}
} catch(SQLException s){s.printStackTrace();}
}
public void delay(){
try {
sleep(1000000000);
} catch(InterruptedException e){}
}
}
This is the error :
Exception in thread "Thread-4" java.lang.NullPointerException
at mypkg.Searching.run(Searching.java:47)
FYI : Line 47 is pointing to
ResultSet rs = stmt.executeQuery("select kode_barang, nama_barang, jumlah_stok, " +
"minimal_stok, harga_jual, deskripsi_barang from BARANG WHERE (kode_barang LIKE " +
"'"+masukan+"%')");
Please help me solve the problem. Thank you very much. :D
NullPointerExceptions are the most easy ones to fix with a debugger. Just place a breakpoint on that line and see what is null.
If the line you posted is correct, you do not even need a debugger since the only thing that can throw the exception is stmt which will be null.
Note:
It is a good thing to run your DB query in a separate Thread to avoid blocking the UI. However, in your case you are updating the UI from that Thread which is not allowed and will cause weird issues. All Swing components must be accessed on the Event Dispatch Thread (EDT). Consult the Swing concurrency tutorial for more information
I do hope you are not starting up a separate Thread on each keystroke in the textfield as you indicated in your question. Looking at the code in the Thread, you remove all elements from the table and then re-add rows. So if a users types in 5 characters at a normal typing speed, you will launch 5 threads which most likely run all at the same time (since a DB connection might not be that fast if your network is lagging). That means that with your current code 5 Threads are, at the same time, removing the table model and adding rows. Even if you put all the Swing code on the EDT (see my first point), you still end up with 5 threads posting runnables on the EDT messing with your table model. I do not know what the resulting table model will be, but probably not what you want
Clearly stmt is null.
You declare it here:
private Statement stmt;
List<Barang> dataSBarang =new LinkedList();
boolean searchBarang=true;
Searching sBarang;
But I don't see any initialization code anywhere, so most likely it remains null for this method call:
private void inputkodeTFMouseClicked(java.awt.event.MouseEvent evt){
sBarang = new Searching( stmt, dataSBarang, modelDetail, tabelDetailBarang, inputkodeTF, searchBarang);
sBarang.start();
}
Related
I would like to parallelize my program to be fast, so my program is like that:
Sim1 sim1 = new Sim1();
for(Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
Double sim = sim1.prob(word_m, entry.getValue());
sim_avg.put(k, sim);
score += sim;
}
and prob in the method in class Sim1 like that
public double prob(String w_i, HashSet<String> set_i){
Similarity sim = new Similarity();
double score = 1;
Iterator<String> it = set_i.iterator();
while (it.hasNext()) {
score += sim.computeSim(w_i, it.next());
}
score = score/set_i.size();
return score;
}
and computeSim in the method in classe Similarity like that :
public double computeSim(String w_1, String w_2){
return cmp(w_1,w_2);
}
So I would like to use thread for the first method and thread for the second method, I tried different ways but I failed
Any help, please
Thank you
You can change the first method code as below. We can try this by using Executor framework by submitting the work of prob() method as Callable task so that It can be executed in different thread, and then by using Future we can get the result for that particular call, for this we need to maintain one more map of key and corresponding Future object, Please see below code to understand it better, hope it may help you.
Sim1 sim1 = new Sim1();
Map<Integer, Future<Double>> workerMap = new HashMap<>();
ExecutorService exe = Executors.newCachedThreadPool();
for(Map.Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
workerMap.put(k, exe.submit(()->{ //Java 8 lamda
return sim1.prob(word_m, entry.getValue());
}));
}
//This loop is to get the result of prob() method for all the keys and process them further
for(Map.Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
try {
Double sim = workerMap.get(k).get();
sim_avg.put(k, sim);
score += sim;
} catch (Exception e) {
e.printStackTrace();
}
}
I will suggest you to google the working of Callable and Future in java, You can see this link also.
I'm working on a project using Unity 4.6.1 and I'm experiencing a weird issue: I have a bool variable which is initially set to false, and I'm trying to set it to true in the Start() method. First of all, it happens that the function in the same script gets called before the Start() method from another script (which should not be happening?) and secondly, the line ready = true; in Start() seems to be having no effect. Here's the relevant code:
public int ready = 0;
void Start()
{
texts = new List<string>(3);
texts.Add("");
texts.Add("");
texts.Add("");
text1.text = texts[0];
text2.text = texts[1];
text3.text = texts[2];
Debug.Log("Setting ready to true");
ready = true;
}
public void showText(string text)
{
Debug.Log("Ready=" + ready);
if (!ready)
return;
texts.Insert(2, texts[1]);
texts.Insert(1, texts[0]);
texts.Insert(0, text);
}
The log output for a run is:
16:07:03.563: Setting ready to true
16:07:24.831: Ready=0
Why is this happening?!
You made a simple mistake. You declared the ready variable as int instead of bool.
Change public int ready = 0;
to
public bool ready = false;
Also, since ready is public, make sure that it is not set to false in the Editor. If you are NOT sure about this, make ready a private variable. So, replace public with private. My first answer should solve your problem.
Before posting the question I decided to try using an int variable instead of a boolean and I forgot the change it back, which is why the int declaration is a mistake in the question above. It seems the Start() or Awake() method was not called at all because I instantiated the class using the new operator. I made the class extend MonoBehaviour, inserted an empty GameObject as a parent for the Text objects and did the following:
GameObject canvas = GameObject.Find("canvas");
uiController = canvas.AddComponent<UIText>();
The code in Awake() was changed to:
GameObject canvas = GameObject.Find("canvas");
text1 = canvas.transform.FindChild("Text1").GetComponent<Text>();
text2 = canvas.transform.FindChild("Text2").GetComponent<Text>();
text3 = canvas.transform.FindChild("Text3").GetComponent<Text>();
texts = new List<string>(3);
texts.Add("");
texts.Add("");
texts.Add("");
text1.text = texts[0];
text2.text = texts[1];
text3.text = texts[2];
Here I coding for get each and every StudyUID(as string) from database to SqlDataReader,but i need to know how the reader value call to forloop execution.
Get to read each and every StudyUID for execution.Here is the code :.
public void automaticreport()
{
//string autsdyid="";
SqlConnection con = new SqlConnection(constr);
con.Open();
string autoquery = "Select StudyUID From StudyTable Where status='2'";
SqlCommand cmd = new SqlCommand(autoquery, con);
SqlDataReader rdr = cmd.ExecuteReader();
for()
{
//how to call each StudyUId from database through for loop
if (!this.reportchk)
{
Reportnew cf = new Reportnew();
ThreadPool.QueueUserWorkItem((WaitCallback)(o => cf.ReportRetrive(this, autsdyid, true)));
}
else
{
int num = (int)System.Windows.Forms.MessageBox.Show("Reports checking in progress, Please wait sometime and try again later", "OPTICS", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
con.Close();
}
Like #R.T and others have mentioned you can use the Read method on the data reader. Looking at your sample code you might want to refactor it slightly to meet more of the SOLID principles and make sure you're not leaking database connections
Here's an example of code that has been refactored a bit.
public void automaticreport()
{
foreach (var autsdyid in LoadStudyIdentifiers())
{
if (!this.reportchk)
{
Reportnew cf = new Reportnew();
ThreadPool.QueueUserWorkItem((WaitCallback)(o => cf.ReportRetrive(this, autsdyid, true)));
}
else
{
int num = (int)System.Windows.Forms.MessageBox.Show("Reports checking in progress, Please wait sometime and try again later", "OPTICS", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
}
private string[] LoadStudyIdentifiers()
{
var results = new List<string>();
// adding a using statement will close the database connection if there are any errors
// avoiding consuming the database connection pool
using (var con = new SqlConnection(constr))
{
conn.Open();
var autoquery = "Select StudyUID From StudyTable Where status='2'";
using (var cmd = new SqlCommand(autoquery, con))
{
SqlDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
results.Add(rdr.GetString(rdr.GetOrdinal("StudyUID")));
}
}
}
return results.ToArray();
}
Note: I wrote this in notepad so there is no guarantee it will compile but should give an indication as to how you could refactor your code.
if (rdr.HasRows)
{
while (rdr.Read())
{
Console.WriteLine(rdr.getString("columnName"));
}
}
You can use something like:
while (reader.Read())
{
string value = reader.getString("columnName");
}
You may use the while loop like this:
while (rdr.Read())
{
string s = rdr.GetString(rdr.GetOrdinal("Column"));
//Apply logic to retrieve here
}
So, I made a class that takes arrays and calculates a value from them. I then decided (unknowingly) to incorporate it into a GUI interface. All went well until I noticed this strange error; one of the jtextfields (prarie) would not store text while the other (yard) does.
I looked around and found my problem similiar to mine on this site;
Updating text in a JTextField
But he had one that doesn't work at all, where I have one that works and one that doesn't.
The Code is here (it's a bit long, but most of it is GUI), so hold your breath!:
import java.awt.GridLayout;
import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Window {
/**
* #param args
*/
private static int numb;
private static double micro, centi;
private static JTextField[] yard,prarie;
private static double[] charges,distances;
public static void main(String[] args)
{
//create a small dialog window to take in number of charged objects
JPanel startup = new JPanel();
JTextField many = new JTextField(5);
startup.add(many);
int result = JOptionPane.showConfirmDialog(null,startup , "Please Enter How Many Charged Objects are Being Evaluated", JOptionPane.OK_CANCEL_OPTION);
many.requestFocusInWindow();
//once ok is clicked, then the number input will be stored under 'numb'
//then proceed to inputFields
if (result == JOptionPane.OK_OPTION)
{
numb = Integer.parseInt(many.getText());
inputFields();
}
}
//this window opens the various JTextFields for input
public static void inputFields()
{
//top JTextFields
yard = new JTextField[numb];
JPanel chargePanel = new JPanel();
for(int x=0;x<numb;x++)
{
yard[x] =new JTextField(5);
chargePanel.add(new JLabel("Charge "+ Integer.toString(x+1)+":"));
chargePanel.add(yard[x]);
chargePanel.add(Box.createVerticalStrut(15)); // a spacer
}
//bottom JTextFields
prarie = new JTextField[numb-1];
JPanel meterPanel = new JPanel();
for(int x=0;x<numb-1;x++)
{
prarie[x]=new JTextField(5);
meterPanel.add(new JLabel("Meters "+ Integer.toString(x+1)+":"));
meterPanel.add(new JTextField(5));
meterPanel.add(Box.createVerticalStrut(15)); // a spacer
}
//JCheckBoxes
JCheckBox isMicro = new JCheckBox("Charges are in terms of microCoulombs");
JCheckBox isCm = new JCheckBox("Distances are in terms of centiMeters");
JPanel chechBox = new JPanel();
chechBox.add(isMicro);
chechBox.add(Box.createVerticalStrut(20));
chechBox.add(isCm);
//Paste them all together into one window
GridLayout gufi = new GridLayout(3,1);
JPanel host = new JPanel(gufi);
host.add(chargePanel);
host.add(meterPanel);
host.add(chechBox);
int result1 = JOptionPane.showConfirmDialog(null, host, "Please Enter Charge and Distance Values", JOptionPane.OK_CANCEL_OPTION);
//if ok is clicked, then go to 'printArr()' to print the JTextFields
//then go to assign the values from the JTextFields to private double arrays 'yard' and 'prarie'
if (result1 == JOptionPane.OK_OPTION)
{
micro = (isMicro.isSelected())? Math.pow(10, -6): 1;
centi = (isCm.isSelected())? .01: 1;
printArr();
assign();
}
}
//a makeshift method to print the value from the JTextFields
//to fix the problem of why prarie wouldn't store numbers
public static void printArr()
{
System.out.println("Charges are:");
for(int x=0;x<numb;x++)
System.out.print(yard[x].getText() + " ");
System.out.println("Distances are:");
for(int x=0;x<numb-1;x++)
System.out.print(prarie[x].getText() + " ");
}
//assigns values from JTextFields to the private double arrays 'yard' and 'prarie'
public static void assign()
{
try {
charges = new double[numb];
for(int x=0;x<numb;x++)
charges[x]=micro*Double.parseDouble(yard[x].getText().trim());
distances = new double[numb-1];
for(int x=0;x<numb-1;x++)
distances[x]=centi*Double.parseDouble(prarie[x].getText().trim());
} catch (NumberFormatException e) {
e.printStackTrace();
//inputFields();
}
calculate();
}
public static void calculate()
{
JPanel sample = new JPanel();
JTextField whichOne = new JTextField(5);
sample.add(whichOne);
int result = JOptionPane.showConfirmDialog(null,sample , "Please Enter Which Charged Object thy Wishs For", JOptionPane.OK_CANCEL_OPTION);
whichOne.requestFocusInWindow();
if (result == JOptionPane.OK_OPTION)
{
int target = Integer.parseInt(whichOne.getText());
}
}
}
Anyone who runs the code and takes the time to enter dummy values will see that 'yard' stores values while 'prarie' does not. Why is this?
*I'm pretty sure I'm overlooking obvious (as always).
Change:
meterPanel.add(new JTextField(5));
to:
meterPanel.add(prarie[x]);
in the for loop for the prarie textfields
Using C# 4 in a Windows console application that continually reports progress how can I make the "redraw" of the screen more fluid?
I'd like to do one of the following:
- Have it only "redraw" the part of the screen that's changing (the progress portion) and leave the rest as is.
- "Redraw" the whole screen but not have it flicker.
Currently I re-write all the text (application name, etc.). Like this:
Console.Clear();
WriteTitle();
Console.WriteLine();
Console.WriteLine("Deleting:\t{0} of {1} ({2})".FormatString(count.ToString("N0"), total.ToString("N0"), (count / (decimal)total).ToString("P2")));
Which causes a lot of flickering.
Try Console.SetCursorPosition. More details here: How can I update the current line in a C# Windows Console App?
static void Main(string[] args)
{
Console.SetCursorPosition(0, 0);
Console.Write("################################");
for (int row = 1; row < 10; row++)
{
Console.SetCursorPosition(0, row);
Console.Write("# #");
}
Console.SetCursorPosition(0, 10);
Console.Write("################################");
int data = 1;
System.Diagnostics.Stopwatch clock = new System.Diagnostics.Stopwatch();
clock.Start();
while (true)
{
data++;
Console.SetCursorPosition(1, 2);
Console.Write("Current Value: " + data.ToString());
Console.SetCursorPosition(1, 3);
Console.Write("Running Time: " + clock.Elapsed.TotalSeconds.ToString());
Thread.Sleep(1000);
}
Console.ReadKey();
}
I know this question is a bit old but I found if you set Console.CursorVisible = false then the flickering stops as well.
Here's a simple working demo that shows multi-line usage without flickering. It shows the current time and a random string every second.
private static void StatusUpdate()
{
var whiteSpace = new StringBuilder();
whiteSpace.Append(' ', 10);
var random = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var randomWord = new string(Enumerable.Repeat(chars, random.Next(10)).Select(s => s[random.Next(s.Length)]).ToArray());
while (true)
{
Console.SetCursorPosition(0, 0);
var sb = new StringBuilder();
sb.AppendLine($"Program Status:{whiteSpace}");
sb.AppendLine("-------------------------------");
sb.AppendLine($"Last Updated: {DateTime.Now}{whiteSpace}");
sb.AppendLine($"Random Word: {randomWord}{whiteSpace}");
sb.AppendLine("-------------------------------");
Console.Write(sb);
Thread.Sleep(1000);
}
}
The above example assumes your console window is blank to start. If not, make sure to use Console.Clear() first.
Technical Note:
SetCursorPosition(0,0) places the cursor back to the top (0,0) so the next call to Console.Write will start from line 0, char 0. Note, it doesn't delete the previous content before writing. As an example, if you write "asdf" over a previous line such as "0123456", you'll end up with something like "asdf456" on that line. For that reason, we use a whiteSpace variable to ensure any lingering characters from the previous line are overwritten with blank spaces. Adjust the length of the whiteSpace variable to meet your needs. You only need the whiteSpace variable for lines that change.
Personal Note:
For my purposes, I wanted to show the applications current status (once a second) along with a bunch of other status information and I wanted to avoid any annoying flickering that can happen when you use Console.Clear(). In my application, I run my status updates behind a separate thread so it constantly provides updates even though I have numerous other threads and long running tasks going at the same time.
Credits:
Thanks to previous posters and dtb for the random string generator used in the demo.
How can I generate random alphanumeric strings in C#?
You could try to hack something together using the core libraries.
Rather than waste your time for sub-standard results, I would check out this C# port of the ncurses library (which is a library used for formatting console output):
Curses Sharp
I think you can use \r in Windows console to return the beginning of a line.
You could also use SetCursorPosition.
I would recommend the following extension methods. They allow you to use a StringBuilder to refresh the console view without any flicker, and also tidies up any residual characters on each line
The Problem: The following demo demonstrates using a standard StringBuilder, where updating lines that are shorter than the previously written line get jumbled up. It does this by writing a short string, then a long string on a loop:
public static void Main(string[] args)
{
var switchTextLength = false;
while(true)
{
var sb = new StringBuilder();
if (switchTextLength)
sb.AppendLine("Short msg");
else
sb.AppendLine("Longer message");
sb.UpdateConsole();
switchTextLength = !switchTextLength;
Thread.Sleep(500);
}
}
Result:
The Solution: By using the extension method provided below, the issue is resolved
public static void Main(string[] args)
{
var switchTextLength = false;
while(true)
{
var sb = new StringBuilder();
if (switchTextLength)
sb.AppendLineEx("Short msg");
else
sb.AppendLineEx("Longer message");
sb.UpdateConsole();
switchTextLength = !switchTextLength;
Thread.Sleep(500);
}
}
Result:
Extension Methods:
public static class StringBuilderExtensions
{
/// <summary>
/// Allows StrinbBuilder callers to append a line and blank out the remaining characters for the length of the console buffer width
/// </summary>
public static void AppendLineEx(this StringBuilder c, string msg)
{
// Append the actual line
c.Append(msg);
// Add blanking chars for the rest of the buffer
c.Append(' ', Console.BufferWidth - msg.Length - 1);
// Finish the line
c.Append(Environment.NewLine);
}
/// <summary>
/// Combines two StringBuilders using AppendLineEx
/// </summary>
public static void AppendEx(this StringBuilder c, StringBuilder toAdd)
{
foreach (var line in toAdd.ReadLines())
{
c.AppendLineEx(line);
}
}
/// <summary>
/// Hides the console cursor, resets its position and writes out the string builder
/// </summary>
public static void UpdateConsole(this StringBuilder c)
{
// Ensure the cursor is hidden
if (Console.CursorVisible) Console.CursorVisible = false;
// Reset the cursor position to the top of the console and write out the string builder
Console.SetCursorPosition(0, 0);
Console.WriteLine(c);
}
}
I actually had this issue so I made a quick simple method to try and eliminate this.
static void Clear(string text, int x, int y)
{
char[] textChars = text.ToCharArray();
string newText = "";
//Converts the string you just wrote into a blank string
foreach(char c in textChars)
{
text = text.Replace(c, ' ');
}
newText = text;
//Sets the cursor position
Console.SetCursorPosition(x, y);
//Writes the blank string over the old string
Console.WriteLine(newText);
//Resets cursor position
Console.SetCursorPosition(0, 0);
}
It actually worked surprisingly well and I hope it may work for you!
Naive approach but for simple applications is working:
protected string clearBuffer = null; // Clear this if window size changes
protected void ClearConsole()
{
if (clearBuffer == null)
{
var line = "".PadLeft(Console.WindowWidth, ' ');
var lines = new StringBuilder();
for (var i = 0; i < Console.WindowHeight; i++)
{
lines.AppendLine(line);
}
clearBuffer = lines.ToString();
}
Console.SetCursorPosition(0, 0);
Console.Write(clearBuffer);
Console.SetCursorPosition(0, 0);
}
Console.SetCursorPosition(0, 0); //Instead of Console.Clear();
WriteTitle();
Console.WriteLine();
Console.WriteLine("Deleting:\t{0} of {1} ({2})".FormatString(count.ToString("N0")