java getting stack overflow-program is not recursive - java

I have been working on my "Random Trivia" program and I keep getting stack overflow with NO recursiveness, at least I cannot find any, here is the code to Gui.java, the main class(and only class)
package mods.giantnuker.random_trivia;
import java.awt.event.ActionEvent;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import mods.giantnuker.javautil.FileFilterAccessor;
import mods.giantnuker.javautil.Pair;
import mods.giantnuker.javautil.PairList;
import mods.giantnuker.javautil.file.parser.XMLParser;
import javax.swing.JFileChooser;
#SuppressWarnings("serial")
public class Gui extends JFrame implements ActionListener, ItemListener {
String tsn;
JFileChooser dialg;
JPanel welcome, newt;
JButton sbttn, nbttn, ebttn, nqb, nab, dqb, dab, sav, ext;
#SuppressWarnings("rawtypes")
JComboBox questions, answers;
List<Pair<String, PairList<String, Integer>>> trivia;
public static void main(String[] args) {
new Gui();
}
#SuppressWarnings({ "static-access", "rawtypes" })
public Gui() {
super("Random Trivia");
this.setSize(300, 250);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
//New
newt = new JPanel();
newt.setLayout(new BoxLayout(newt, BoxLayout.Y_AXIS));
questions = new JComboBox();
questions.addItemListener(this);
answers = new JComboBox();
nqb = new JButton("New Question+ ");
nab = new JButton("New Answer+ ");
dqb = new JButton("-Delete Question");
dab = new JButton("-Delete Answer ");
sav = new JButton("*Save ");
ext = new JButton("-Exit- ");
nqb.addActionListener(this);
nab.addActionListener(this);
dqb.addActionListener(this);
dab.addActionListener(this);
sav.addActionListener(this);
ext.addActionListener(this);
newt.add(questions);
newt.add(answers);
newt.add(nqb);
newt.add(nab);
newt.add(dqb);
newt.add(dab);
newt.add(sav);
newt.add(ext);
//Welcome
welcome = new JPanel();
welcome.setLayout(new BoxLayout(welcome, BoxLayout.Y_AXIS));
welcome.add(new JLabel("Welcome To Random Trivia!"));
welcome.add(sbttn = new JButton("Select a file(.trv) to use"));
welcome.add(nbttn = new JButton("Create a new one"));
welcome.add(ebttn = new JButton("Or edit an old one"));
sbttn.addActionListener(this);
nbttn.addActionListener(this);
ebttn.addActionListener(this);
dialg = new JFileChooser();
dialg.setDialogType(dialg.OPEN_DIALOG);
dialg.setFileFilter(new FileFilterAccessor("trv"));
this.add(welcome);
this.setVisible(true);
}
#SuppressWarnings({ "unchecked", "rawtypes", "static-access" })
#Override
public void actionPerformed(ActionEvent arg0) {
Object src = arg0.getSource();
if (src == sbttn) {
dialg.setDialogType(dialg.OPEN_DIALOG);
List<Map<String, Integer>> trivia = new ArrayList();
int out = dialg.showOpenDialog(null);
if(out == 0) {
File f = dialg.getSelectedFile();
}
}
if (src == nbttn) {
trivia = new ArrayList();
this.remove(welcome);
this.add(newt);
this.setVisible(true);
}
if (src == ebttn) {
dialg.setDialogType(dialg.OPEN_DIALOG);
int out = dialg.showOpenDialog(null);
if(out == 0) {
trivia = parse(dialg.getSelectedFile());
this.remove(welcome);
this.add(newt);
ref();
this.setVisible(true);
}
}
if (src == ext) {
this.remove(newt);
this.add(welcome);
this.setVisible(true);
}
if (src == nqb) {
String txt = JOptionPane.showInputDialog(this ,"Enter the Question:", "Question...");
if (txt.length() > 0 && !txt.equals("Question...")) {
trivia.add(new Pair(txt, new PairList()));
questions.addItem(txt);
}
}
if (src == nab) {
if (questions.getItemCount() == 0) {
JOptionPane.showMessageDialog(this, "You must select a question or create one!", "Error", JOptionPane.WARNING_MESSAGE);
return;
}
String txt = JOptionPane.showInputDialog(this ,"Enter the Answer:", "Answer...");
String txt2 = JOptionPane.showInputDialog(this ,"Enter the amount of points for the Answer:", "Points...");
if (txt.length() > 0 && !txt.equals("Answer...")) {
if (txt2.length() > 0 && !txt2.equals("Points...")) {
int points = 0;
boolean err = true;
while(err) {
try {
points = Integer.valueOf(txt2);
err = false;
} catch (NumberFormatException e) {
txt2 = JOptionPane.showInputDialog(this ,"Enter the amount of points for the Answer:", "Points...");
if (txt2.equals("Points...")) return;
}
}
trivia.get(questions.getSelectedIndex()).getB().add(txt, points);
answers.addItem(txt + "(" + points + " points)");
}
}
}
if (src == dab) {
if (questions.getItemCount() == 0) {
JOptionPane.showMessageDialog(this, "You must select a question!", "Error", JOptionPane.WARNING_MESSAGE);
return;
}
if (answers.getItemCount() != 0) {
trivia.get(questions.getSelectedIndex()).getB().remove(answers.getSelectedIndex());
answers.removeItemAt(answers.getSelectedIndex());
}
}
if (src == dqb) {
if (questions.getItemCount() != 0) {
trivia.remove(trivia.get(questions.getSelectedIndex()));
questions.removeItemAt(questions.getSelectedIndex());
ref();
}
}
if (src == sav) {
tsn = JOptionPane.showInputDialog(this ,"Enter the name of the Trivia:", "Name...");
if (!tsn.equals("Name...")) newTriviaSave();
}
}
#SuppressWarnings("static-access")
public void newTriviaSave() {
dialg.setDialogType(dialg.SAVE_DIALOG);
int out = dialg.showSaveDialog(null);
if(out == 0) {
File f = dialg.getSelectedFile();
if (!f.getPath().contains(".")) {
f = new File(f.getPath() + ".trv");
}
System.out.println(f.getPath());
toFile(f, trivia, tsn);
}
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public List<Pair<String, PairList<String, Integer>>> parse(File f) {
List<Pair<String, PairList<String, Integer>>> trivia = new ArrayList();
XMLParser p = new XMLParser(f);
try {
p.read();
p.doc.getDocumentElement().normalize();
NodeList l = p.doc.getElementsByTagName("trivia");
Element root = (Element) l.item(0);
tsn = root.getAttribute("name");
l = root.getElementsByTagName("question");
for (int i = 0; i < l.getLength(); i++) {
Element question = (Element)l.item(i);
NodeList l2 = question.getElementsByTagName("answer");
PairList<String, Integer> answers = new PairList();
for (int j = 0; j < l2.getLength(); j++) {
Element answer = (Element)l2.item(j);
answers.add(answer.getAttribute("text"), Integer.valueOf(answer.getAttribute("points")));
}
trivia.add(new Pair(question.getAttribute("text"), answers));
}
} catch (Exception e) {
}
return trivia;
}
public void toFile(File f, List<Pair<String, PairList<String, Integer>>> questions, String name) {
XMLParser p = new XMLParser(f);
try {
p.create();
Element root = p.doc.createElement("trivia");
root.setAttribute("name", name);
for (Pair<String, PairList<String, Integer>> question : questions) {
Element questionE = p.doc.createElement("question");
questionE.setAttribute("text", question.getA());
for (Pair<String, Integer> answer : question.getB()) {
Element answerE = p.doc.createElement("answer");
answerE.setAttribute("text", answer.getA());
answerE.setAttribute("points", String.valueOf(answer.getB()));
questionE.appendChild(answerE);
}
root.appendChild(questionE);
}
p.doc.appendChild(root);
p.write();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void itemStateChanged(ItemEvent arg0) {
Object src = arg0.getSource();
if (src == questions) {
ref();
}
}
#SuppressWarnings("unchecked")
public void ref() {
questions.removeAllItems();
answers.removeAllItems();
for (Pair<String, PairList<String, Integer>> p : trivia) {
questions.addItem(p.getA());
}
if (questions.getItemCount() != 0) {
PairList<String, Integer> answes = trivia.get(questions.getSelectedIndex()).getB();
for (Pair<String, Integer> ans : answes) {
answers.addItem(ans.getA() + "(" + ans.getB() + " points)");
}
}
}
}
JavaUtil works fine - not related to it.
Here is a runnable jar with JavaUtil prepackaged.
to get my error, click on "edit an old one" and open the following file(just a dummy file, you could make your own and get the same result)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<trivia name="Dummy Trivia">
<question text="dum">
<answer points="1" text="ans1"/>
</question><question text="dum2">
<answer points="1" text="ans1"/>
<answer points="2" text="ans2"/>
</question>
<question text="dum3">
<answer points="1" text="ans1"/>
<answer points="2" text="ans2"/>
<answer points="3" text="ans3"/>
</question>
</trivia>
Thank you :)
EDIT: Stack overflow is in ref() \ stands for refresh
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at javax.swing.plaf.basic.BasicComboBoxUI$Handler.contentsChanged(BasicComboBoxUI.java:1858)
at javax.swing.plaf.basic.BasicComboBoxUI$Handler.intervalRemoved(BasicComboBoxUI.java:1877)
at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:179)
at javax.swing.DefaultComboBoxModel.removeAllElements(DefaultComboBoxModel.java:174)
at javax.swing.JComboBox.removeAllItems(JComboBox.java:771)
at mods.giantnuker.random_trivia.Gui.ref(Gui.java:264)
at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280)
at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118)
at javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93)
at javax.swing.DefaultComboBoxModel.addElement(DefaultComboBoxModel.java:131)
at javax.swing.JComboBox.addItem(JComboBox.java:716)
at mods.giantnuker.random_trivia.Gui.ref(Gui.java:267)
at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1271)
at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
at javax.swing.JComboBox.intervalRemoved(JComboBox.java:1351)
at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:179)
at javax.swing.DefaultComboBoxModel.removeAllElements(DefaultComboBoxModel.java:174)
at javax.swing.JComboBox.removeAllItems(JComboBox.java:771)
at mods.giantnuker.random_trivia.Gui.ref(Gui.java:264)
at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280)
at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118)
at javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93)
at javax.swing.DefaultComboBoxModel.addElement(DefaultComboBoxModel.java:131)
at javax.swing.JComboBox.addItem(JComboBox.java:716)
at mods.giantnuker.random_trivia.Gui.ref(Gui.java:267)
Continuing...

Looking at your stack trace, we see a problem centered on the ref() method and removing components from a JComboBox.
There appears to be a problem here:
#Override
public void itemStateChanged(ItemEvent arg0) {
Object src = arg0.getSource();
if (src == questions) {
ref();
}
}
#SuppressWarnings("unchecked")
public void ref() {
questions.removeAllItems();
answers.removeAllItems();
...
Your ItemListener, (this -- which has been added to both questions and answers JComboBoxes) calls the ref() method which changes the state of both JComboBoxs, which triggers the ItemListener, which calls the ref() method ..... ad infinitum.
Don't change the state of an object from within one of its listeners, or if you absolutely need to do this, then inactivate or remove the listeners first, and then re-add them. e.g.,
public void ref() {
// first remove all item listeners
ItemListener[] questionListeners = questions.getItemListeners();
ItemListener[] answerListeners = answers.getItemListeners();
for (ItemListener l : questionListeners) {
questions.removeItemListener(l);
}
for (ItemListener l : answerListeners) {
answers.removeItemListener(l);
}
// change state
questions.removeAllItems();
answers.removeAllItems();
// re-add all listeners
for (ItemListener l : questionListeners) {
questions.addItemListener(l);
}
for (ItemListener l : answerListeners) {
answers.addItemListener(l);
}
...

boolean err = true;
while(err) {
try {
points = Integer.valueOf(txt2);
err = false;
} catch (NumberFormatException e) {
txt2 = JOptionPane.showInputDialog(this, "Enter the amount of points for the Answer:", "Points...");
if (txt2.equals("Points..."))
return;
}
}
I am looking into this. if text2 is not a number, it will throw an exception, and it won't set err to false. This might cause the loop to go on infinitely assuming text2 is not equal to "Points..."

Related

how i can change the end of r.keyPress(KeyEvent.VK_W) the W out of the VK

Alright, So im doing Keypressed and keyreleased, and that works with VK_ stuff.... i have a GUi ready and im able to save and load config files, but i was wondering on how i can change the end of r.keyPress(KeyEvent.VK_W) the W out of the VK with my code....
Here is my main
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class Main {
public static void main(String[] args) throws Exception{
Config bot = new Config();
bot.setVerbose(true);
bot.connect("irc.twitch.tv", 6667, "oauth:6u54pi07uzegv42dwee65gpgzmwwgi");
bot.joinChannel("#mmolegion");
JFrame frame = new JFrame("TwitchBot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(700, 500));
frame.setLocationRelativeTo(null);
frame.setResizable(true);
KeyGetter.LoadKeys();
try {
Config.loadConfig();
} catch (Exception e) {
e.printStackTrace();
}
JMenuBar mb = new JMenuBar();
JMenu file = new JMenu("File");
mb.add(file);
JMenu edit = new JMenu("Edit");
mb.add(edit);
JMenuItem options = new JMenuItem("Options");
options.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Config.openConfig(frame);
}
});
frame.setJMenuBar(mb);
edit.add(options);
frame.pack();
frame.setVisible(true);
}
}
and he is my Config
import java.awt.Choice;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.jibble.pircbot.PircBot;
public class Config extends PircBot{
public static String left = "up", right = "right", up = "up", down = "down";
private static ArrayList<Choice> choices;
public Config() {
this.setName("Rex__Bot");
}
public void onMessage(String channel, String sender, String login, String hostname, String message) {
if(message.equals("up")) {
try {
Robot r = new Robot();
r.keyPress(KeyEvent.VK_W);
r.delay(300);
r.keyRelease(KeyEvent.VK_W);
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
public static void openConfig(JFrame frame){
choices = new ArrayList<Choice>();
JFrame options = new JFrame("Options");
options.setSize(600, 400);
options.setResizable(false);
options.setLocationRelativeTo(frame);
options.setLayout(null);
Choice left = addChoice("left", options, 30, 30);
left.select(Config.left);
Choice right = addChoice("right", options, 30, 80);
right.select(Config.right);
Choice up = addChoice("up", options, 150, 30);
up.select(Config.up);
Choice down = addChoice("down", options, 150, 80);
down.select(Config.down);
JButton done = new JButton("ok");
done.setBounds(150, 220, 100, 30);
done.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
options.dispose();
saveChanges();
}
});
options.add(done);
options.setVisible(true);
}
public static void saveChanges(){
Choice left = choices.get(0);
Choice right = choices.get(1);
Choice up = choices.get(2);
Choice down = choices.get(3);
Config.left = left.getSelectedItem();
Config.right = right.getSelectedItem();
Config.up = up.getSelectedItem();
Config.down = down.getSelectedItem();
try{
saveConfig();
}
catch(Exception e){
e.printStackTrace();
}
}
public static Choice addChoice(String name, JFrame options, int x, int y){
JLabel label = new JLabel(name);
label.setBounds(x, y - 20, 100, 20);
Choice key = new Choice();
for(String s: getKeyNames()){
key.add(s);
}
key.setBounds(x, y, 100, 20);
options.add(key);
options.add(label);
choices.add(key);
return key;
}
public static ArrayList<String> getKeyNames(){
ArrayList<String> result = new ArrayList<String>();
for(String s: KeyGetter.keyNames){
result.add(s);
if(s.equalsIgnoreCase("F24")){
break;
}
}
return result;
}
public static void loadConfig() throws Exception{
File directory = new File(getDefaultDirectory(), "/Twitchbot");
if(!directory.exists()){
directory.mkdirs();
}
File config = new File(directory,"config.txt");
if(!config.exists()){
config.createNewFile();
System.out.println("File not found, saving default");
saveConfig();
return;
}
#SuppressWarnings("resource")
Scanner s = new Scanner(config);
HashMap<String, String> values = new HashMap<String, String>();
while(s.hasNextLine()){
String[] entry = s.nextLine().split(":");
String key = entry[0];
String value = entry[1];
values.put(key, value);
}
if(!values.containsKey("left") || !values.containsKey("right") || !values.containsKey("up") || !values.containsKey("down")){
System.out.println("Invalid names in config, saving default config");
saveConfig();
return;
}
String left = values.get("left");
String right = values.get("right");
String up = values.get("up");
String down = values.get("down");
if(!(getKeyNames().contains(left) && getKeyNames().contains(right) && getKeyNames().contains(up) && getKeyNames().contains(down))){
System.out.println("Invalid key in config, saving default config");
}
Config.left = left;
Config.right = right;
Config.up = up;
Config.down = down;
}
public static void saveConfig() throws Exception{
File directory = new File(getDefaultDirectory(), "/Twitchbot");
if(!directory.exists()){
directory.mkdirs();
}
File config = new File(directory,"config.txt");
PrintWriter pw = new PrintWriter(config);
pw.println("left:" + left);
pw.println("right:" + right);
pw.println("up:" + up);
pw.println("down:" + down);
pw.close();
}
public static String getDefaultDirectory(){
String OS = System.getProperty("os.name").toUpperCase();
if(OS.contains("WIN")){
return System.getenv("APPDATA");
}
if(OS.contains("MAC")){
return System.getProperty("user.home") + "Library/Application Support";
}
return System.getProperty("user.home");
}
}
and here is my KeyGetter
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
public class KeyGetter {
public static HashMap<String, Integer> keys;
public static ArrayList<String> keyNames;
public static void LoadKeys(){
keys = new HashMap<String, Integer>();
keyNames = new ArrayList<String>();
Field[] fields = KeyEvent.class.getFields();
for(Field f: fields){
if(Modifier.isStatic(f.getModifiers())){
if(f.getName().startsWith("VK")){
try{
int num = f.getInt(null);
String name = KeyEvent.getKeyText(num);
keys.put(name, num);
keyNames.add(name);
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
}
So is there anyway of changing the The last letter of VK_W with my config file?
I don't know if you can do this.
Why don't you just save int values. For example KeyEvent.VK_W transforms to:
public static final int VK_W = 87;
So it would be much easier if you would just save int walues to your configuration.
Here can you find the whole list:
KeyEvent.VK_W
So you can just use the following code:
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 87) {
System.out.println("W pressed");
}
}
Instead of:
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W) {
System.out.println("W pressed");
}
}

Using a JComboBox on a JFileChooser to list all files that begin with text of first row of combo box

I managed to get a delete button on a JFileChooser. I figured out where to put the button. In the process, I figured out, by messing with the getComponents() method, where the JTextField where the file is searched for and replaced it with a JComboBox. The plan is to get it to list all the files that begin with the text in the first row, the only one that can be edited on the JComboBox, otherwise it's uneditable, and it could select an item in another row and it would set the text of the item at the first row to the text of that item. (And also update the JCombobBox, though I don't think I implemented that part yet, though a simple method call should do that, but, anyway, I tried posting this on Java Programming Forums.
It's showing the items in there, but it's not letting it update with the typing. It is, instead, showing all the items in the directory. Also, when I go to select an item, it removes the first row and sets the text of the first row to the item. However, it now makes the first row uneditable I think or does something wacky.
It is removing the first row because the brilliant people who developed the JComboBox class couldn't bother to make a setItmeAt(Object item, int index) method, only a getItemAt(int index). So I had to get the text of the item, put it in a variable, remove the item at the first row, and then readd at the first row an item that has the text of the selected item.
I fear that maybe my code was too long, so I made it shorter, though even doing that today got no results at the Java Programming Forums, as the issue is with the JComboBox and the File class and stuff.
package addressbook.gui;
import javax.swing.JFileChooser;
import java.io.File;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JOptionPane;
import javax.swing.JComboBox;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.MutableComboBoxModel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.plaf.basic.BasicComboPopup;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class FileChooserWithDelete extends JFileChooser
{
private String textFieldString;
private JIntelligentComboBox comboBox;
private DefaultComboBoxModel dcm;
public FileChooserWithDelete()
{
super("./");
dcm = new DefaultComboBoxModel();
java.io.File f = getCurrentDirectory();
java.io.File[] files = f.listFiles();
for (int i =0; i < files.length; i++)
{
dcm.addElement(new Object[] {files[i].getName(), "", 0});
}
JButton delete = new JButton("Delete");
delete.setToolTipText("Delete file");
comboBox = new JIntelligentComboBox(dcm);
addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
JFileChooser chooser = (JFileChooser) evt.getSource();
java.io.File oldDir = (java.io.File) evt.getOldValue();
java.io.File newDir = (java.io.File) evt.getNewValue();
java.io.File curDir = chooser.getCurrentDirectory();
System.out.println(curDir.getName());
dcm.removeAllElements();
java.io.File[] moreFiles = curDir.listFiles();
System.out.println("Obama is a loser!");
for (int i =0; i < moreFiles.length; i++)
{
dcm.addElement(new Object[] {moreFiles[i].getName(), "", 0});
}
comboBox.init();
}
}
});
java.awt.Container cont = (java.awt.Container) (getComponents()[3]);
java.awt.Container cont2 = (java.awt.Container) (cont.getComponents()[3]);
java.awt.Container cont3 = (java.awt.Container) (cont.getComponents()[0]);
cont3.remove(1);
cont3.add(comboBox, 1);
delete.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
File f= getSelectedFile();
java.awt.Container cont = (java.awt.Container) (getComponents()[3]);
java.awt.Container cont2 = (java.awt.Container) (cont.getComponents()[3]);
java.awt.Container cont3 = (java.awt.Container) (cont.getComponents()[0]);
//javax.swing.JTextField jtf = (javax.swing.JTextField) (cont3.getComponents()[1]);
String text = (String) comboBox.getItemAt(0);
if (f == null)
f = new File("./" + text);
int option = JOptionPane.showConfirmDialog(null, "Are you sure you wnat to delete?", "Delete file " + f.getName() + "?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.YES_OPTION)
{
if (!f.exists() || text == null)
{
JOptionPane.showMessageDialog(null, "File doesn't exist.", "Could not find file.", JOptionPane.ERROR_MESSAGE);
cancelSelection();
}
else
{
f.delete();
cancelSelection();
}
}
}});
cont2.setLayout(new java.awt.FlowLayout());
//((java.awt.Container) (getComponents()[3])).add(delete);
cont2.add(delete);
//cont2.add(delete);
}
protected class JIntelligentComboBox extends JComboBox {
private List<Object> itemBackup = new ArrayList<Object>();
public JIntelligentComboBox(MutableComboBoxModel aModel) {
super(aModel);
init();
}
private void init() {
this.setRenderer(new searchRenderer());
this.setEditor(new searchComboBoxEditor());
this.setEditable(true);
int size = this.getModel().getSize();
Object[] tmp = new Object[this.getModel().getSize()];
for (int i = 0; i < size; i++) {
tmp[i] = this.getModel().getElementAt(i);
itemBackup.add(tmp[i]);
}
this.removeAllItems();
this.getModel().addElement(new Object[]{"", "", 0});
for (int i = 0; i < tmp.length; i++) {
this.getModel().addElement(tmp[i]);
}
final JTextField jtf = (JTextField) this.getEditor().getEditorComponent();
jtf.addKeyListener(
new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
searchAndListEntries(jtf.getText());
}
});
}
#Override
public MutableComboBoxModel getModel() {
return (MutableComboBoxModel) super.getModel();
}
private void searchAndListEntries(Object searchFor) {
List<Object> found = new ArrayList<Object>();
for (int i = 0; i < this.itemBackup.size(); i++) {
Object tmp = this.itemBackup.get(i);
if (tmp == null || searchFor == null) {
continue;
}
Object[] o = (Object[]) tmp;
String s = (String) o[0];
/*
if (s.matches("(?i).*" + searchFor + ".*")) {
found.add(new Object[]{
((Object[]) tmp)[0], searchFor, ((Object[]) tmp)[2]
});
}
}
*/
if (s.startsWith((String) searchFor))
found.add(new Object[] {((Object[]) tmp) [0], searchFor, ((Object[]) tmp) [2]});}
this.removeAllItems();
this.getModel().addElement(new Object[]{searchFor, searchFor, 0});
for (int i = 0; i < found.size(); i++) {
this.getModel().addElement(found.get(i));
}
this.setPopupVisible(true);
// http://stackoverflow.com/questions/7605995
BasicComboPopup popup =
(BasicComboPopup) this.getAccessibleContext().getAccessibleChild(0);
Window popupWindow = SwingUtilities.windowForComponent(popup);
Window comboWindow = SwingUtilities.windowForComponent(this);
if (comboWindow.equals(popupWindow)) {
Component c = popup.getParent();
Dimension d = c.getPreferredSize();
c.setPreferredSize(d);
}
else {
popupWindow.pack();
}
}
class searchRenderer extends BasicComboBoxRenderer {
#Override
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (index == 0) {
setText("");
return this;
}
Object[] v = (Object[]) value;
String s = (String) v[0];
String lowerS = s.toLowerCase();
String sf = (String) v[1];
String lowerSf = sf.toLowerCase();
List<String> notMatching = new ArrayList<String>();
if (!sf.equals("")) {
int fs = -1;
int lastFs = 0;
while ((fs = lowerS.indexOf(lowerSf, (lastFs == 0) ? -1 : lastFs)) > -1) {
notMatching.add(s.substring(lastFs, fs));
lastFs = fs + sf.length();
}
notMatching.add(s.substring(lastFs));
}
String html = "";
if (notMatching.size() > 1) {
html = notMatching.get(0);
int start = html.length();
int sfl = sf.length();
for (int i = 1; i < notMatching.size(); i++) {
String t = notMatching.get(i);
html += "<b style=\"color: black;\">"
+ s.substring(start, start + sfl) + "</b>" + t;
start += sfl + t.length();
}
}
this.setText("<html><head></head><body style=\"color: gray;\">"
+ html + "</body></head>");
return this;
}
}
class searchComboBoxEditor extends BasicComboBoxEditor {
public searchComboBoxEditor() {
super();
}
#Override
public void setItem(Object anObject) {
if (anObject == null) {
super.setItem(anObject);
}
else {
Object[] o = (Object[]) anObject;
super.setItem(o[0]);
}
}
#Override
public Object getItem() {
return new Object[]{super.getItem(), super.getItem(), 0};
}
}
}
public JTextField getComboBoxTextField()
{
final JTextField jtf = (JTextField) comboBox.getEditor().getEditorComponent();
return jtf;
}
public static void main(String[] args)
{
FileChooserWithDelete fcwd = new FileChooserWithDelete();
fcwd.showOpenDialog(null);
}
}
The link to the page at the java programming forum is here.
You may be able to adapt the approach examined here. For notification, you may be able to leverage an existing JFileChooser event, as shown here. Alternatively, you can define your own PropertyChangeEvent, as shown here.
I have got it to work. However, there is a problem. The following lines are causing it to make ALL of my popups (i.e. JPopupMenu, JMenu, etc), scrunched so that you can't really read the titles on them.
The following lines seem to be the culprit.
BasicComboPopup popup =
(BasicComboPopup) this.getAccessibleContext().getAccessibleChild(0);
Window popupWindow = SwingUtilities.windowForComponent(popup);
Window comboWindow = SwingUtilities.windowForComponent(this);
if (comboWindow.equals(popupWindow)) {
Component c = popup.getParent();
Dimension d = c.getPreferredSize();
c.setPreferredSize(d);
}
else {
popupWindow.pack();
}
What is that bit doing? When I take it out, it gets rid of the error.
package addressbook.gui;
import javax.swing.JFileChooser;
import java.io.File;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JOptionPane;
import javax.swing.JComboBox;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.MutableComboBoxModel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.plaf.basic.BasicComboPopup;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
import javax.swing.JCheckBox;
import javax.swing.BorderFactory;
public class FileChooserWithDelete extends JFileChooser
{
private String textFieldString;
private JIntelligentComboBox comboBox;
private DefaultComboBoxModel dcm;
private JCheckBox read, write, execute;
public FileChooserWithDelete()
{
super("./");
dcm = new DefaultComboBoxModel();
java.io.File f = getCurrentDirectory();
java.io.File[] files = f.listFiles();
for (int i =0; i < files.length; i++)
{
dcm.addElement(new Object[] {files[i].getName(), "", 0});
}
JButton delete = new JButton("Delete");
delete.setToolTipText("Delete file");
comboBox = new JIntelligentComboBox(dcm);
addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
JFileChooser chooser = (JFileChooser) evt.getSource();
java.io.File oldDir = (java.io.File) evt.getOldValue();
java.io.File newDir = (java.io.File) evt.getNewValue();
java.io.File curDir = chooser.getCurrentDirectory();
System.out.println(curDir.getName());
/*
//dcm.removeAllElements();
comboBox.removeAllItems();
dcm.removeAllElements();
java.io.File[] moreFiles = curDir.listFiles();
System.out.println("Obama is a loser!");
for (int i =0; i < moreFiles.length; i++)
{
dcm.addElement(new Object[] {moreFiles[i].getName(), "", 0});
//comboBox.insertItemAt(moreFiles[i].getName(), i);
}
for (int i =0; i < comboBox.getItemCount(); i++)
{
System.out.println(java.util.Arrays.toString((Object[]) comboBox.getItemAt(i)));
}
// comboBox.init();
*/
comboBox.updateFiles();
}
}
});
java.awt.Container cont = (java.awt.Container) (getComponents()[3]);
java.awt.Container cont2 = (java.awt.Container) (cont.getComponents()[3]);
java.awt.Container cont3 = (java.awt.Container) (cont.getComponents()[0]);
read = new JCheckBox("Read");
write = new JCheckBox("Write");
execute = new JCheckBox("Execute");
JPanel checkBoxPanel = new JPanel();
checkBoxPanel.setBorder(BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));
cont3.remove(1);
cont3.add(comboBox, 1);
checkBoxPanel.setLayout(new java.awt.FlowLayout());
checkBoxPanel.add(read);
checkBoxPanel.add(write);
checkBoxPanel.add(execute);
read.setEnabled(false);
write.setEnabled(false);
execute.setEnabled(false);
addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e2)
{
if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY
.equals(e2.getPropertyName())) {
JFileChooser chooser = (JFileChooser)e2.getSource();
File oldFile = (File)e2.getOldValue();
File newFile = (File)e2.getNewValue();
// The selected file should always be the same as newFile
File curFile = chooser.getSelectedFile();
try
{
if (curFile.canRead())
{
read.setSelected(true);
}
else
{
read.setSelected(false);
}
if (curFile.canWrite())
{
write.setSelected(true);
}
else
{
write.setSelected(false);
}
if (curFile.canExecute())
{
execute.setSelected(true);
}
else
{
execute.setSelected(false);
}
}
catch(NullPointerException npe)
{
return;
}
}
}
});
delete.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
File f= getSelectedFile();
java.awt.Container cont = (java.awt.Container) (getComponents()[3]);
java.awt.Container cont2 = (java.awt.Container) (cont.getComponents()[3]);
java.awt.Container cont3 = (java.awt.Container) (cont.getComponents()[0]);
//javax.swing.JTextField jtf = (javax.swing.JTextField) (cont3.getComponents()[1]);
String text = (String) comboBox.getItemAt(0);
if (f == null)
f = new File("./" + text);
int option = JOptionPane.showConfirmDialog(null, "Are you sure you wnat to delete?", "Delete file " + f.getName() + "?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.YES_OPTION)
{
if (!f.exists() || text == null)
{
JOptionPane.showMessageDialog(null, "File doesn't exist.", "Could not find file.", JOptionPane.ERROR_MESSAGE);
cancelSelection();
}
else
{
f.delete();
cancelSelection();
}
}
}});
cont2.setLayout(new java.awt.FlowLayout());
//((java.awt.Container) (getComponents()[3])).add(delete);
cont2.add(delete);
cont2.add(checkBoxPanel);
}
protected class JIntelligentComboBox extends JComboBox {
private List<Object> itemBackup = new ArrayList<Object>();
public JIntelligentComboBox(MutableComboBoxModel aModel) {
super(aModel);
init();
}
private void init() {
this.setRenderer(new searchRenderer());
this.setEditor(new searchComboBoxEditor());
this.setEditable(true);
int size = this.getModel().getSize();
Object[] tmp = new Object[this.getModel().getSize()];
for (int i = 0; i < size; i++) {
tmp[i] = this.getModel().getElementAt(i);
itemBackup.add(tmp[i]);
}
this.removeAllItems();
this.getModel().addElement(new Object[]{"", "", 0});
for (int i = 0; i < tmp.length; i++) {
this.getModel().addElement(tmp[i]);
}
final JTextField jtf = (JTextField) this.getEditor().getEditorComponent();
jtf.addKeyListener(
new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
searchAndListEntries(jtf.getText());
}
});
}
#Override
public MutableComboBoxModel getModel() {
return (MutableComboBoxModel) super.getModel();
}
private void updateFiles()
{
itemBackup.clear();
java.io.File f = getCurrentDirectory();
java.io.File[] files = f.listFiles();
for (int i =0; i < files.length; i++)
{
itemBackup.add(new Object[] {files[i].getName(), "", 0});
}
}
private void searchAndListEntries(Object searchFor) {
List<Object> found = new ArrayList<Object>();
for (int i =0; i < itemBackup.size(); i++)
{
System.out.println(java.util.Arrays.toString((Object[])itemBackup.get(i)));
}
for (int i = 0; i < this.itemBackup.size(); i++) {
Object tmp = this.itemBackup.get(i);
if (tmp == null || searchFor == null) {
continue;
}
Object[] o = (Object[]) tmp;
String s = (String) o[0];
/*
if (s.matches("(?i).*" + searchFor + ".*")) {
found.add(new Object[]{
((Object[]) tmp)[0], searchFor, ((Object[]) tmp)[2]
});
}
}
*/
if (s.startsWith((String) searchFor))
found.add(new Object[] {((Object[]) tmp) [0], searchFor, ((Object[]) tmp) [2]});}
this.removeAllItems();
this.getModel().addElement(new Object[]{searchFor, searchFor, 0});
for (int i = 0; i < found.size(); i++) {
this.getModel().addElement(found.get(i));
}
this.setPopupVisible(true);
// http://stackoverflow.com/questions/7605995\
/*
BasicComboPopup popup =
(BasicComboPopup) this.getAccessibleContext().getAccessibleChild(0);
Window popupWindow = SwingUtilities.windowForComponent(popup);
Window comboWindow = SwingUtilities.windowForComponent(this);
if (comboWindow.equals(popupWindow)) {
Component c = popup.getParent();
Dimension d = c.getPreferredSize();
c.setPreferredSize(d);
}
else {
popupWindow.pack();
}
*/
System.out.println("break");
for (int i =0; i < found.size(); i++)
{
System.out.println(java.util.Arrays.toString((Object[]) found.get(i)));
}
}
class searchRenderer extends BasicComboBoxRenderer {
#Override
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (index == 0) {
setText("");
return this;
}
Object[] v = (Object[]) value;
String s = (String) v[0];
String lowerS = s.toLowerCase();
String sf = (String) v[1];
String lowerSf = sf.toLowerCase();
List<String> notMatching = new ArrayList<String>();
if (!sf.equals("")) {
int fs = -1;
int lastFs = 0;
while ((fs = lowerS.indexOf(lowerSf, (lastFs == 0) ? -1 : lastFs)) > -1) {
notMatching.add(s.substring(lastFs, fs));
lastFs = fs + sf.length();
}
notMatching.add(s.substring(lastFs));
}
String html = "";
if (notMatching.size() > 1) {
html = notMatching.get(0);
int start = html.length();
int sfl = sf.length();
for (int i = 1; i < notMatching.size(); i++) {
String t = notMatching.get(i);
html += "<b style=\"color: black;\">"
+ s.substring(start, start + sfl) + "</b>" + t;
start += sfl + t.length();
}
}
this.setText("<html><head></head><body style=\"color: gray;\">"
+ html + "</body></head>");
return this;
}
}
class searchComboBoxEditor extends BasicComboBoxEditor {
public searchComboBoxEditor() {
super();
}
#Override
public void setItem(Object anObject) {
if (anObject == null) {
super.setItem(anObject);
}
else {
Object[] o = (Object[]) anObject;
super.setItem(o[0]);
}
}
#Override
public Object getItem() {
return new Object[]{super.getItem(), super.getItem(), 0};
}
}
}
public JTextField getComboBoxTextField()
{
final JTextField jtf = (JTextField) comboBox.getEditor().getEditorComponent();
return jtf;
}
}

Is the transfer data for transferables from outside the jvm null by default when the TransferHandler canImport method gets called?

I'm working on Drag & Drop support for a JList component and I would like to be able to support files dragged in from my file browser. I however only want to allow files and not folders to be dragged in. Thus I'm trying to check for it in my TransferHandler like this:
#Override
public boolean canImport(TransferSupport support) {
if (support.getComponent().equals(this.resourceFileList)) {
if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
} else {
try {
// get file list
Transferable transferable = support.getTransferable();
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
// check for folders
boolean containsFiles = false;
List files = (List) transferData;
for (int i = 0; i < files.size(); i++) {
File file = (File) files.get(i);
if (!file.isDirectory()) {
containsFiles = true;
}
}
// return file indicator
return containsFiles;
} catch (IOException | UnsupportedFlavorException e) {
System.out.println("Unable to check for folders due to the following exception:\n" + e);
return false;
}
}
} else {
return false;
}
}
Unfortunately transferData seems to be null here. It is however not when the TransferHandler's importData method gets called. Does anyone have any clue if this is a bug of some sorts or desired behaviour?
I'm on a Mac (OSX 10.8) if it makes a difference and Java version is 1.7.0_21.
Thanks in advance!
EDIT:
Here's a short SSCCE for anyone to test. Just a drag a file into the list and watch the console.
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
public class DNDIssue extends TransferHandler {
#Override
public boolean canImport(TransferSupport support) {
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
try {
Transferable transferable = support.getTransferable();
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor); // <-- this returns null
System.out.println(transferData); // null
} catch (IOException | UnsupportedFlavorException e) {
System.out.println("Unable to check for folders due to the following exception:\n" + e);
} finally {
return false;
}
} else {
return false;
}
}
public static void main(String[] args) {
// create window
JFrame window = new JFrame("DNDIssue");
window.setSize(640, 480);
window.setLocation(100, 100);
// create list with model and set transfer handler
JList<File> list = new JList<File>(new DefaultListModel<File>());
list.setTransferHandler(new DNDIssue());
// add enclosing scroll pane and display window
window.getContentPane().add(new JScrollPane(list));
window.setVisible(true);
}
}
Your SSCCE works fine for me using JDK 1.7.0_21 on Windows 7 64bit.
Could you try following code?
Transferable transferable = support.getTransferable();
System.out.println("----");
String mt = DataFlavor.javaFileListFlavor.getMimeType();
for(DataFlavor df: transferable.getTransferDataFlavors()) {
System.out.println(df.getMimeType());
System.out.println(" "+df.getMimeType().equals(mt));
}
SSCCE 1.0: delete
SSCCE 1.1: Override TransferHandler#importData(...) version
InvalidDnDOperationException: No drop current
java.awt.dnd.InvalidDnDOperationException: No drop current
at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:245)
at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
at FileTransferHandler.canImport(DNDIssueTest.java:64)
The problem is possibly related to Bug ID 6759788 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6759788
via: http://www.coderanch.com/t/466319/GUI/java/Drag-Drop
SSCCE 1.2: Ignore InvalidDnDOperationException
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.io.*;
import java.util.List;
import javax.swing.*;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
public class DNDIssueTest {
public JComponent makeUI() {
// create list with model and set transfer handler
JList<File> list = new JList<File>(new DefaultListModel<File>());
list.setDropMode(DropMode.INSERT);
list.setTransferHandler(new FileTransferHandler());
return new JScrollPane(list);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new DNDIssueTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class FileTransferHandler extends TransferHandler {
private static final boolean DEBUG = true;
#SuppressWarnings("unchecked")
#Override public boolean importData(TransferSupport support) {
try {
List files = (List)support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
System.out.println("importData");
if(!hasDirectory(files) && canImport(support)) {
JList list = (JList)support.getComponent();
DefaultListModel model = (DefaultListModel)list.getModel();
for(Object o: files) {
model.addElement(o);
}
return true;
}
} catch(Exception ex) {
ex.printStackTrace();
}
return false;
}
private boolean hasDirectory(List list) {
System.out.println("hasDirectory check");
for (Object o: list) {
if(o instanceof File) {
File file = (File) o;
if (file.isDirectory()) {
return true;
}
}
}
return false;
}
#Override public boolean canImport(TransferSupport support) {
if(!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
if(!DEBUG) return true;
Transferable transferable = support.getTransferable();
try {
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
//System.out.println(transferData); // null
System.out.println("canImport");
return !hasDirectory((List)transferData);
} catch (Exception e) {
//e.printStackTrace();
System.out.println("*** Ignore InvalidDnDOperationException ***");
return true;
}
}
}
SSCCE 2.0: DropTargetListener version
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.*;
import java.util.List;
import javax.swing.*;
public class DNDIssueTest2 {
public JComponent makeUI() {
final DefaultListModel<File> model = new DefaultListModel<>();
JList<File> list = new JList<File>(model);
DropTargetListener dtl = new DropTargetAdapter() {
#Override public void dragOver(DropTargetDragEvent dtde) {
if(dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
Transferable transferable = dtde.getTransferable();
Object transferData = null;
try {
transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
} catch(Exception ex) {
dtde.rejectDrag();
return;
}
List<File> files = (List<File>)transferData;
for (int i = 0; i < files.size(); i++) {
File file = (File) files.get(i);
if (file.isDirectory()) {
dtde.rejectDrag();
return;
}
}
dtde.acceptDrag(DnDConstants.ACTION_COPY);
return;
}
dtde.rejectDrag();
}
#Override public void drop(DropTargetDropEvent dtde) {
try {
if(dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
Transferable transferable = dtde.getTransferable();
List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor);
for(Object o: list) {
if(o instanceof File) {
File file = (File) o;
model.addElement(file);
}
}
dtde.dropComplete(true);
return;
}
} catch(UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
dtde.rejectDrop();
}
};
new DropTarget(list, DnDConstants.ACTION_COPY, dtl, true);
return new JScrollPane(list);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new DNDIssueTest2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

jcombobox filter in java - Look and feel independent

I have a simple JComboBox filter code like this :
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class FilterComboBox extends JComboBox {
private List<String> array;
public FilterComboBox(List<String> array) {
super(array.toArray());
this.array = array;
this.setEditable(true);
final JTextField textfield = (JTextField) this.getEditor().getEditorComponent();
textfield.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
}
});
}
});
}
public void comboFilter(String enteredText) {
List<String> filterArray= new ArrayList<String>();
for (int i = 0; i < array.size(); i++) {
if (array.get(i).toLowerCase().contains(enteredText.toLowerCase())) {
filterArray.add(array.get(i));
}
}
if (filterArray.size() > 0) {
this.setModel(new DefaultComboBoxModel(filterArray.toArray()));
this.setSelectedItem(enteredText);
this.showPopup();
}
else {
this.hidePopup();
}
}
/* Testing Codes */
public static List<String> populateArray() {
List<String> test = new ArrayList<String>();
test.add("");
test.add("Mountain Flight");
test.add("Mount Climbing");
test.add("Trekking");
test.add("Rafting");
test.add("Jungle Safari");
test.add("Bungie Jumping");
test.add("Para Gliding");
return test;
}
public static void makeUI() {
JFrame frame = new JFrame("Adventure in Nepal - Combo Filter Test");
FilterComboBox acb = new FilterComboBox(populateArray());
frame.getContentPane().add(acb);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
makeUI();
}
}
The performance of the combo filter is not so good but it is fine for few data set. My problem is - when I remove the comment UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); to change look and feel, the filter doesn't work. In WindowsLookAndFeel, the combo box only takes single character in it by replacing the previously entered character.
Can you please tell me whats going on? Manoj Shrestha's answer below helps in some way but , can you please provide some other suggestions to achieve combo box filter in Java?
Firstly you are creating new model everytime and then invoking show popup from code which leads to flickering etc. We can modify the model itself. Secondly you set the currently entered text as selected item which seems to have selectAll behavior as noted by others. I have modified the code as follows:
public void comboFilter(String enteredText) {
if (!this.isPopupVisible()) {
this.showPopup();
}
List<String> filterArray= new ArrayList<String>();
for (int i = 0; i < array.size(); i++) {
if (array.get(i).toLowerCase().contains(enteredText.toLowerCase())) {
filterArray.add(array.get(i));
}
}
if (filterArray.size() > 0) {
DefaultComboBoxModel model = (DefaultComboBoxModel) this.getModel();
model.removeAllElements();
for (String s: filterArray)
model.addElement(s);
JTextField textfield = (JTextField) this.getEditor().getEditorComponent();
textfield.setText(enteredText);
}
}
Hope it works for you.
very long answer, I think that exelent example about how different Look and Feel have got implemented methods in API and works
KeyListener isn't proper Listener for Swing JComponents, you really to have bothering with KeyBindings,
KeyListener is simple asynchronous,
JComboBox is Compound JComponent, then there is required override internal JComponents, all output from KeyListener must be wrapped into invokeLater(), notice I can create event from coumpond JComponents that twice invokeLater() doesn't returns expected output to the GUI, only Swing Timer with Swing Action can do that correctly, simple why to bothering wiht that example about wrong way,
code
import java.awt.Component;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class ComboBoxHoverOver {
private JComboBox combo = new JComboBox();
public ComboBoxHoverOver() {
combo.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXX");
combo.setRenderer(new ComboToolTipRenderer(combo));
combo.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
//System.out.println(combo.getSelectedItem().toString());
}
});
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//System.out.println(combo.getSelectedItem().toString());
}
});
combo.addItem("");
combo.addItem("Long text 4");
combo.addItem("Long text 3");
combo.addItem("Long text 2");
combo.addItem("Long text 1");
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(combo);
f.pack();
f.setVisible(true);
}
private class ComboToolTipRenderer extends BasicComboBoxRenderer {
private static final long serialVersionUID = 1L;
private JComboBox combo;
private JList comboList;
ComboToolTipRenderer(JComboBox combo) {
this.combo = combo;
}
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
if (comboList == null) {
comboList = list;
KeyAdapter listener = new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_UP) {
int x = 5;
int y = comboList.indexToLocation(comboList.getSelectedIndex()).y;
System.out.println(comboList.getSelectedIndex());
}
}
};
combo.addKeyListener(listener);
combo.getEditor().getEditorComponent().addKeyListener(listener);
}
if (isSelected) {
//System.out.println(value.toString());
}
return this;
}
}
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ComboBoxHoverOver comboBoxHoverOver = new ComboBoxHoverOver();
}
});
}
}
JComboBox is Compound JComponent, then there is required override BasicComboBoxUI, please sorry I lazy to write and simulating too much longer code as code from first point
otherwise all effort from above two point are useless and contraproductive, nothing else, only DOT
please can someone to test follows code in *nix and apple OS X
from my Java6 WinXP compo (all important is hidden in the used methods, enless kudos for anonymous author from former Sun Microsystems)
Substance L&F
WindowsLookAndFeel L&F
Nimbus L&F
Metal L&F
from Java Classes
main
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import org.pushingpixels.substance.api.skin.SubstanceOfficeSilver2007LookAndFeel;
public class AutoCompleteTextField {
private static JFrame frame = new JFrame();
private ArrayList<String> listSomeString = new ArrayList<String>();
private Java2sAutoTextField someTextField = new Java2sAutoTextField(listSomeString);
private ArrayList<String> listSomeAnotherString = new ArrayList<String>();
private Java2sAutoComboBox someComboBox = new Java2sAutoComboBox(listSomeAnotherString);
public AutoCompleteTextField() {
listSomeString.add("-");
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
listSomeString.add("Pool");
listSomeString.add("None of the above");
//
listSomeAnotherString.add("-");
listSomeAnotherString.add("XxxZxx Snowboarding");
listSomeAnotherString.add("AaaBbb Rowing");
listSomeAnotherString.add("CccDdd Knitting");
listSomeAnotherString.add("Eee Fff Speed reading");
listSomeAnotherString.add("Eee Fff Pool");
listSomeAnotherString.add("Eee Fff None of the above");
//
someTextField.setFont(new Font("Serif", Font.BOLD, 16));
someTextField.setForeground(Color.black);
someTextField.setBackground(Color.orange);
someTextField.setName("someTextField");
someTextField.setDataList(listSomeString);
//
someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
someComboBox.setForeground(Color.black);
someComboBox.setBackground(Color.YELLOW);
someComboBox.getEditor().selectAll();
someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
((JTextField) someComboBox.getEditor().getEditorComponent()).setDisabledTextColor(Color.black);
someComboBox.setName("someComboBox");
someComboBox.setDataList(listSomeAnotherString);
//
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(someTextField);
frame.add(someComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
//
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
someTextField.setText("-");
someComboBox.getEditor().setItem(0);
someComboBox.getEditor().selectAll();
someTextField.grabFocus();
someTextField.requestFocus();
someTextField.setText(someTextField.getText());
someTextField.selectAll();
}
});
}
public static void main(String[] args) {
/*SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel());
SwingUtilities.updateComponentTreeUI(frame);
} catch (UnsupportedLookAndFeelException e) {
throw new RuntimeException(e);
}
}
});*/
/*try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.out.println(info.getName());
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}*/
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
AutoCompleteTextField aCTF = new AutoCompleteTextField();
}
});
}
}
AutoComboBox
import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.plaf.basic.BasicComboBoxEditor;
public class Java2sAutoComboBox extends JComboBox {
private static final long serialVersionUID = 1L;
private AutoTextFieldEditor autoTextFieldEditor;
private boolean isFired;
private class AutoTextFieldEditor extends BasicComboBoxEditor {
private Java2sAutoTextField getAutoTextFieldEditor() {
return (Java2sAutoTextField) editor;
}
AutoTextFieldEditor(java.util.List<String> list) {
editor = new Java2sAutoTextField(list, Java2sAutoComboBox.this);
}
}
public Java2sAutoComboBox(java.util.List<String> list) {
isFired = false;
autoTextFieldEditor = new AutoTextFieldEditor(list);
setEditable(true);
setModel(new DefaultComboBoxModel(list.toArray()) {
private static final long serialVersionUID = 1L;
#Override
protected void fireContentsChanged(Object obj, int i, int j) {
if (!isFired) {
super.fireContentsChanged(obj, i, j);
}
}
});
setEditor(autoTextFieldEditor);
}
public boolean isCaseSensitive() {
return autoTextFieldEditor.getAutoTextFieldEditor().isCaseSensitive();
}
public void setCaseSensitive(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setCaseSensitive(flag);
}
public boolean isStrict() {
return autoTextFieldEditor.getAutoTextFieldEditor().isStrict();
}
public void setStrict(boolean flag) {
autoTextFieldEditor.getAutoTextFieldEditor().setStrict(flag);
}
public java.util.List<String> getDataList() {
return autoTextFieldEditor.getAutoTextFieldEditor().getDataList();
}
public void setDataList(java.util.List<String> list) {
autoTextFieldEditor.getAutoTextFieldEditor().setDataList(list);
setModel(new DefaultComboBoxModel(list.toArray()));
}
void setSelectedValue(Object obj) {
if (isFired) {
return;
} else {
isFired = true;
setSelectedItem(obj);
fireItemStateChanged(new ItemEvent(this, 701, selectedItemReminder, 1));
isFired = false;
return;
}
}
#Override
protected void fireActionEvent() {
if (!isFired) {
super.fireActionEvent();
}
}
}
AutoTextField
import java.util.List;
import javax.swing.JTextField;
import javax.swing.text.*;
public class Java2sAutoTextField extends JTextField {
private static final long serialVersionUID = 1L;
private List<String> dataList;
private boolean isCaseSensitive;
private boolean isStrict;
private Java2sAutoComboBox autoComboBox;
public class AutoDocument extends PlainDocument {
private static final long serialVersionUID = 1L;
#Override
public void replace(int i, int j, String s, AttributeSet attributeset)
throws BadLocationException {
super.remove(i, j);
insertString(i, s, attributeset);
}
#Override
public void insertString(int i, String s, AttributeSet attributeset)
throws BadLocationException {
if (s == null || "".equals(s)) {
return;
}
String s1 = getText(0, i);
String s2 = getMatch(s1 + s);
int j = (i + s.length()) - 1;
if (isStrict && s2 == null) {
s2 = getMatch(s1);
j--;
} else if (!isStrict && s2 == null) {
super.insertString(i, s, attributeset);
return;
}
if (autoComboBox != null && s2 != null) {
autoComboBox.setSelectedValue(s2);
}
super.remove(0, getLength());
super.insertString(0, s2, attributeset);
setSelectionStart(j + 1);
setSelectionEnd(getLength());
}
#Override
public void remove(int i, int j) throws BadLocationException {
int k = getSelectionStart();
if (k > 0) {
k--;
}
String s = getMatch(getText(0, k));
if (!isStrict && s == null) {
super.remove(i, j);
} else {
super.remove(0, getLength());
super.insertString(0, s, null);
}
if (autoComboBox != null && s != null) {
autoComboBox.setSelectedValue(s);
}
try {
setSelectionStart(k);
setSelectionEnd(getLength());
} catch (Exception exception) {
}
}
}
public Java2sAutoTextField(List<String> list) {
isCaseSensitive = false;
isStrict = true;
autoComboBox = null;
if (list == null) {
throw new IllegalArgumentException("values can not be null");
} else {
dataList = list;
init();
return;
}
}
Java2sAutoTextField(List<String> list, Java2sAutoComboBox b) {
isCaseSensitive = false;
isStrict = true;
autoComboBox = null;
if (list == null) {
throw new IllegalArgumentException("values can not be null");
} else {
dataList = list;
autoComboBox = b;
init();
return;
}
}
private void init() {
setDocument(new AutoDocument());
if (isStrict && dataList.size() > 0) {
setText(dataList.get(0).toString());
}
}
private String getMatch(String s) {
for (int i = 0; i < dataList.size(); i++) {
String s1 = dataList.get(i).toString();
if (s1 != null) {
if (!isCaseSensitive
&& s1.toLowerCase().startsWith(s.toLowerCase())) {
return s1;
}
if (isCaseSensitive && s1.startsWith(s)) {
return s1;
}
}
}
return null;
}
#Override
public void replaceSelection(String s) {
AutoDocument _lb = (AutoDocument) getDocument();
if (_lb != null) {
try {
int i = Math.min(getCaret().getDot(), getCaret().getMark());
int j = Math.max(getCaret().getDot(), getCaret().getMark());
_lb.replace(i, j - i, s, null);
} catch (Exception exception) {
}
}
}
public boolean isCaseSensitive() {
return isCaseSensitive;
}
public void setCaseSensitive(boolean flag) {
isCaseSensitive = flag;
}
public boolean isStrict() {
return isStrict;
}
public void setStrict(boolean flag) {
isStrict = flag;
}
public List<String> getDataList() {
return dataList;
}
public void setDataList(List<String> list) {
if (list == null) {
throw new IllegalArgumentException("values can not be null");
} else {
dataList = list;
return;
}
}
}
EDIT
output from Win7 64b / Java7
Metal L&F
Windows L&F (funny empty white space near Button in JComboBox)
Nimbus L&F
feel free for edit(s)
This component is called autocomplete and is included in a so called swing extensions porject.
Just have a look at: http://swingx.java.net/
There is a webstart: http://swinglabs-demos.java.net/demos/swingxset6/swingxset.jnlp
Autocomplete is the Menu to select. Have fun and less error prone code :)
obviously the glitch is in the textfield component used. What happens is, when windows look and feel is used , the text in this component is selected just as using the line "textfield.selectAll();", and hence when you type anything else the selected text is cleared form the textfield component. So in the below code the caret position of this component is adjusted. This is how it works, first store the current caret position of text field in a variable "currentCaretPosition", then move the caret position to the beginning in the text in the component. After filtering restoring the caret position back to the "currentCaretPosition" variable value. I hope it works as you want it to.
The refined code is given below:-
/****Beginning of code****/
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class FilterComboBox extends JComboBox {
private List<String> array;
private int currentCaretPosition=0;
public FilterComboBox(List<String> array) {
super(array.toArray());
this.array = array;
this.setEditable(true);
final JTextField textfield = (JTextField) this.getEditor().getEditorComponent();
textfield.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
currentCaretPosition=textfield.getCaretPosition();
if(textfield.getSelectedText()==null)
{
textfield.setCaretPosition(0);
comboFilter(textfield.getText());
textfield.setCaretPosition(currentCaretPosition);
}
}
});
}
});
}
public void comboFilter(String enteredText) {
List<String> filterArray= new ArrayList<String>();
for (int i = 0; i < array.size(); i++) {
if (array.get(i).toLowerCase().contains(enteredText.toLowerCase())) {
filterArray.add(array.get(i));
}
}
if (filterArray.size() > 0) {
this.setModel(new DefaultComboBoxModel(filterArray.toArray()));
this.setSelectedItem(enteredText);
this.showPopup();
}
else {
this.hidePopup();
}
}
/* Testing Codes */
public static List<String> populateArray() {
List<String> test = new ArrayList<String>();
test.add("");
test.add("Mountain Flight");
test.add("Mount Climbing");
test.add("Trekking");
test.add("Rafting");
test.add("Jungle Safari");
test.add("Bungie Jumping");
test.add("Para Gliding");
return test;
}
public static void makeUI() {
JFrame frame = new JFrame("Adventure in Nepal - Combo Filter Test");
FilterComboBox acb = new FilterComboBox(populateArray());
frame.getContentPane().add(acb);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
makeUI();
}
}
/******* End of code**********/
It looks like, as you mentioned, when user inputs any texts in combobox, the Windows Look & Feel selects (highlights) the entered text. So, when you press another key, it replaces the previous one. So, the solution is not to highlight the entered texts. You can achieve this by adding any one of the following statements in your keylistener.
textfield.setCaretPosition(textfield.getText().length());
OR
textfield.setSelectionStart(textfield.getText().length());
So, your keylistener should look like this :
final JTextField textfield = (JTextField) this.getEditor().getEditorComponent();
textfield.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
textfield.setCaretPosition(textfield.getText().length());
}
});
}
});

Need to identify SwingWorker completion to stop the current process?

My aim is to select all the files named with MANI.txt which is present in their respective folders and then load path of the MANI.txt files different location in table. After I load the path in the table,I used to select needed path and modifiying those.
To load the MANI.txt files taking more time,because it may present more than 30 times in my workspace or etc. until load the files I want to give alarm to the user with help of ProgessBar.Once the list size has been populated I need to disable ProgressBar.
i came up with this ProgressBar, but progress bar operation gets complete or not, if the background process(finding files and putting their path in the table) got completed means, the result getting displayed and hiding the progress bar? i want the presence of progress bar opertion gets complete 100% in either case? please give me some ideas?how to implement it?
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class JTableHeaderCheckBox extends JFrame implements ActionListener {
protected int counter = 0;
Object colNames[] = { "", "Path" };
Object[][] data = {};
DefaultTableModel dtm;
JTable table;
JButton but;
java.util.List list;
File folder;
JProgressBar current;
JFrame fr1, frame;
int num = 0;
JProgressBar pbar;
JTableHeaderCheckBox it;
public void buildGUI() throws InterruptedException {
dtm = new DefaultTableModel(data, colNames);
table = new JTable(dtm);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
int vColIndex = 0;
TableColumn col = table.getColumnModel().getColumn(vColIndex);
int width = 10;
col.setPreferredWidth(width);
int vColIndex1 = 1;
TableColumn col1 = table.getColumnModel().getColumn(vColIndex1);
int width1 = 500;
col1.setPreferredWidth(width1);
JFileChooser chooser = new JFileChooser();
// chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("Choose workSpace Path");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION)
{
}
String path = chooser.getSelectedFile().getAbsolutePath();
folder = new File(path);
but = new JButton("REMOVE");
SwingWorker worker = new SwingWorker() {
#Override
public Object doInBackground() {
GatheringFiles ob = new GatheringFiles();
list = ob.returnlist(folder);
return list;
}
#Override
protected void done() {
// java.util.List list = (java.util.List)get();
for (int x = 0; x < list.size(); x++) {
dtm.addRow(new Object[] { new Boolean(false),
list.get(x).toString() });
}
try {
JPanel pan = new JPanel();
JScrollPane sp = new JScrollPane(table);
TableColumn tc = table.getColumnModel().getColumn(0);
tc.setCellEditor(table.getDefaultEditor(Boolean.class));
tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));
tc.setHeaderRenderer(new CheckBoxHeader(
new MyItemListener()));
JFrame f = new JFrame();
pan.add(sp);
pan.add(but);
f.add(pan);
f.setSize(700, 100);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
if (list.size() >= 0) {
// hide the progress bar
frame.hide();
}
} catch (Exception ex) {
}
}
};
worker.execute();
but.addActionListener(this);
//calling progressbar
if(!path.isEmpty())
{
SwingProgressBar();
}
}
public void SwingProgressBar() {
UIManager.put("ProgressBar.selectionBackground", Color.black);
UIManager.put("ProgressBar.selectionForeground", Color.white);
UIManager.put("ProgressBar.foreground", new Color(8, 32, 128));
pbar = new JProgressBar();
pbar.setMinimum(0);
pbar.setMaximum(100);
pbar.setForeground(Color.RED);
pbar.setStringPainted(true);
it = new JTableHeaderCheckBox();
frame = new JFrame("Loading");
final JLabel lb = new JLabel("0");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setContentPane(it);
frame.add(pbar);
frame.pack();
frame.setVisible(true);
counter = 0;
Thread runner = new Thread() {
public void run() {
counter = 0;
while (counter <= 99) {
Runnable runme = new Runnable() {
public void run() {
pbar.setValue(counter);
}
};
SwingUtilities.invokeLater(runme);
counter++;
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
}
}
};
runner.start();
}
public void updateBar(int newValue) {
pbar.setValue(newValue);
}
class MyItemListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
Object source = e.getSource();
if (source instanceof AbstractButton == false)
return;
boolean checked = e.getStateChange() == ItemEvent.SELECTED;
for (int x = 0, y = table.getRowCount(); x < y; x++) {
table.setValueAt(new Boolean(checked), x, 0);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new JTableHeaderCheckBox().buildGUI();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
} catch (Exception ex) {
}
}
});
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == but) {
System.err.println("table.getRowCount()" + table.getRowCount());
for (int x = 0, y = table.getRowCount(); x < y; x++) {
if ("true".equals(table.getValueAt(x, 0).toString())) {
System.err.println(table.getValueAt(x, 0));
System.err.println(list.get(x).toString());
delete(list.get(x).toString());
}
}
}
}
public void delete(String a) {
String delete = "C:";
System.err.println(a);
try {
File inFile = new File(a);
if (!inFile.isFile()) {
return;
}
// Construct the new file that will later be renamed to the // filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(inFile));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
// Read from the original file and write to the new
// unless content matches data to be removed.
while ((line = br.readLine()) != null) {
System.err.println(line);
line = line.replace(delete, " ");
pw.println(line);
pw.flush();
}
pw.close();
br.close();
// Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
// Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
class CheckBoxHeader extends JCheckBox implements TableCellRenderer,
MouseListener {
protected CheckBoxHeader rendererComponent;
protected int column;
protected boolean mousePressed = false;
public CheckBoxHeader(ItemListener itemListener) {
rendererComponent = this;
rendererComponent.addItemListener(itemListener);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
rendererComponent.setForeground(header.getForeground());
rendererComponent.setBackground(header.getBackground());
rendererComponent.setFont(header.getFont());
header.addMouseListener(rendererComponent);
}
}
setColumn(column);
rendererComponent.setText("Check All");
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return rendererComponent;
}
protected void setColumn(int column) {
this.column = column;
}
public int getColumn() {
return column;
}
protected void handleClickEvent(MouseEvent e) {
if (mousePressed) {
mousePressed = false;
JTableHeader header = (JTableHeader) (e.getSource());
JTable tableView = header.getTable();
TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel(viewColumn);
if (viewColumn == this.column && e.getClickCount() == 1
&& column != -1) {
doClick();
}
}
}
public void mouseClicked(MouseEvent e) {
handleClickEvent(e);
((JTableHeader) e.getSource()).repaint();
}
public void mousePressed(MouseEvent e) {
mousePressed = true;
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
//
import java.io.File;
import java.util.*;
public class GatheringFiles {
public static List returnlist(File folder)
{
List<File> list = new ArrayList<File>();
List<File> list1 = new ArrayList<File>();
getFiles(folder, list);
return list;
}
private static void getFiles(File folder, List<File> list) {
folder.setReadOnly();
File[] files = folder.listFiles();
for(int j = 0; j < files.length; j++) {
if( "MANI.txt".equals(files[j].getName()))
{
list.add(files[j]);
}
if(files[j].isDirectory())
getFiles(files[j], list);
}
}
}

Categories