Related
My JPanel preview is returning null upon calling getGraphics() inside the drawToScreen method. The Test class does extend JPanel also since it's being kept within a TabbedPane. The class also implements Runnable, KeyListener and MouseListener
The log of System.out.println is
javax.swing.JPanel[,172,149,1280x720,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=null]
Below is a sample of the existing code. Running it won't work since it uses outside methods to complete itself but hopefully an answer can be found.
public Test() {
setBackground(Color.DARK_GRAY);
setLayout(null);
preview = new JPanel();
preview.setBounds(172, 149, 1280, 720);
add(preview);
}
public void addNotify() {
preview.addNotify();
if(thread == null) {
thread = new Thread(this);
preview.addKeyListener(this);
preview.addMouseListener(this);
thread.start();
}
}
private void init() {
image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) image.getGraphics();
running = true;
}
private long redraw() {
long t = System.currentTimeMillis();
if(onTab) {
if(!FileManager.isSleeping())
update();
if(!pause) {
draw();
drawToScreen();
}
}
return System.currentTimeMillis() - t;
}
public void run() {
init();
while(running) {
long durationMs = redraw();
try {
Thread.sleep(Math.max(0, FPS - durationMs));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void update () {
reupdateImages();
}
private void draw() {
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0; i < layers.length; i++) {
if(layers[i] != null) {
g.drawImage(
layers[i].getImage(),
layers[i].getX(),
layers[i].getY(),
layers[i].getWidth(),
layers[i].getHeight(),
null
);
g.setColor(Color.red);
for(int j = 0; j < layers.length; j++) {
if(layers[j].isSelected())
g.drawRect(
layers[j].getX(),
layers[j].getY(),
layers[j].getWidth(),
layers[j].getHeight()
);
}
}
}
}
private void drawToScreen() {
System.out.println(preview);
System.out.println(preview.getGraphics());
Graphics g2 = preview.getGraphics();
g2.drawImage(image, 0, 0,
WIDTH, HEIGHT,
null);
panelImage = image;
g2.dispose();
}
As for the rest of the code, upon markspace's request I have added the rest of it just to debunk outside the provided sample.
#SuppressWarnings("serial")
public class ThumbnailEditor extends JPanel implements Runnable, KeyListener, MouseListener {
private JComboBox layerBox;
private int pos = 0;
private JFileChooser jfc;
// automated gui, I'm lazy and its dynamic
private int numberOfLayers = 24; // even numbers only guys and keep above 8
private JPanel preview;
private JSpinner localWidth;
private JSpinner localHeight;
private JSpinner posx;
private JSpinner posy;
private boolean ignore = false;
private JTextField width;
private JTextField height;
private JButton remove;
private JButton add;
private JButton select;
private JButton edit;
// drawing stoof
public int WIDTH = 1280;
public int HEIGHT = 720;
private Thread thread;
private boolean running;
private int FPS = 60;
private File location;
private BufferedImage panelImage;
private BufferedImage image;
private Graphics2D g;
private boolean pause = false;
private boolean onTab = false;
// when it gets too big, annoying issues start to happen with the text. This automatically fixes it
private static int[] overrideSizes = {
8,
9,
10,
11,
12,
14,
16,
18,
20,
22,
24,
26,
28,
36,
48,
72
};
// adjust this, low the more sensitive the changing of the font is.
private static int sensitivity = 4;
// layer stoof
// layer 0 --> at 0. layer 1 --> at 1
private static ThumbnailObject[] layers;
public static TextEditor[] te;
public ThumbnailEditor() {
setBackground(Color.DARK_GRAY);
setLayout(null);
preview = new JPanel();
preview.setBounds(172, 149, 1280, 720);
add(preview);
layerBox = new JComboBox();
layerBox.setBackground(Color.DARK_GRAY);
layerBox.setFont(new Font("Arial Black", Font.BOLD, 14));
layerBox.setBounds(10, 11, 100, 40);
add(layerBox);
add = new JButton("Add");
add.setBackground(Color.DARK_GRAY);
add.setFont(new Font("Arial Black", Font.BOLD, 14));
add.setBounds(120, 11, 100, 40);
add(add);
select = new JButton("Select");
select.setBackground(Color.DARK_GRAY);
select.setFont(new Font("Arial Black", Font.BOLD, 14));
select.setBounds(230, 11, 100, 40);
add(select);
edit = new JButton("Edit");
edit.setBackground(Color.DARK_GRAY);
edit.setFont(new Font("Arial Black", Font.BOLD, 14));
edit.setBounds(340, 11, 100, 40);
add(edit);
remove = new JButton("Remove");
remove.setBackground(Color.DARK_GRAY);
remove.setFont(new Font("Arial Black", Font.BOLD, 14));
remove.setBounds(450, 11, 100, 40);
add(remove);
JButton generate = new JButton("Generate Test Image");
generate.setBackground(Color.DARK_GRAY);
generate.setFont(new Font("Arial Black", Font.BOLD, 14));
generate.setBounds(1376, 11, 239, 40);
add(generate);
JButton deselect = new JButton("Deselect All Layers");
deselect.setBackground(Color.DARK_GRAY);
deselect.setFont(new Font("Arial Black", Font.BOLD, 14));
deselect.setBounds(120, 62, 210, 40);
add(deselect);
JLabel widthLabel = new JLabel("Width");
widthLabel.setHorizontalAlignment(SwingConstants.CENTER);
widthLabel.setForeground(Color.WHITE);
widthLabel.setFont(new Font("Arial Black", Font.BOLD, 14));
widthLabel.setBounds(10, 149, 70, 40);
add(widthLabel);
JLabel heightLabel = new JLabel("Height");
heightLabel.setHorizontalAlignment(SwingConstants.CENTER);
heightLabel.setFont(new Font("Arial Black", Font.BOLD, 14));
heightLabel.setForeground(Color.WHITE);
heightLabel.setBounds(90, 149, 70, 40);
add(heightLabel);
localWidth = new JSpinner();
localWidth.setFont(new Font("Arial Black", Font.BOLD, 14));
localWidth.setBounds(10, 184, 70, 20);
add(localWidth);
localHeight = new JSpinner();
localHeight.setFont(new Font("Arial Black", Font.BOLD, 14));
localHeight.setBounds(90, 184, 70, 20);
add(localHeight);
JLabel xSizeLabel = new JLabel("X");
xSizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
xSizeLabel.setForeground(Color.WHITE);
xSizeLabel.setFont(new Font("Arial Black", Font.BOLD, 14));
xSizeLabel.setBounds(10, 215, 70, 40);
add(xSizeLabel);
JLabel ySizeLabel = new JLabel("Y");
ySizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
ySizeLabel.setForeground(Color.WHITE);
ySizeLabel.setFont(new Font("Arial Black", Font.BOLD, 14));
ySizeLabel.setBounds(90, 215, 70, 40);
add(ySizeLabel);
posx = new JSpinner();
posx.setFont(new Font("Arial Black", Font.BOLD, 14));
posx.setBounds(10, 248, 70, 20);
add(posx);
posy = new JSpinner();
posy.setFont(new Font("Arial Black", Font.BOLD, 14));
posy.setBounds(92, 248, 70, 20);
add(posy);
pause = true;
layers = new ThumbnailObject[numberOfLayers];
te = new TextEditor[numberOfLayers];
for(int i = 0; i < layers.length; i++) {
layers[i] = new ThumbnailObject();
}
for(int i = 0; i < numberOfLayers; i++) {
layerBox.addItem("Layer [" + i + "]");
}
remove.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
pos = layerBox.getSelectedIndex();
layers[pos].reset();
add.setToolTipText("");
if(te[pos] != null) {
te[pos].getFrame().dispose();
te[pos] = null;
}
}
});
select.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pos = layerBox.getSelectedIndex();
if(layers[pos].getImage() != null) {
for(int i = 0; i < layers.length; i++) {
layers[i].setSelected(false);
}
layers[pos].setSelected(true);
localWidth.setValue(layers[pos].getWidth());
localHeight.setValue(layers[pos].getHeight());
posx.setValue(layers[pos].getX());
posy.setValue(layers[pos].getY());
}
}
});
edit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
pos = layerBox.getSelectedIndex();
if(layers[pos].getImage() != null) {
if(te[pos] != null) {
te[pos].getFrame().setVisible(true);
}
}
}
});
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
pos = layerBox.getSelectedIndex();
jfc = new JFileChooser();
jfc.setCurrentDirectory(new java.io.File("user.home"));
jfc.setDialogTitle("Select Layer 0 Image File");
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (jfc.showOpenDialog(add) == JFileChooser.APPROVE_OPTION) {
try {
layers[pos].setFile(jfc.getSelectedFile());
if(!layers[pos].isReversed())
if(layers[pos].getFile().getName().contains(".txt")) {
if(te[pos] == null)
te[pos] = new TextEditor(pos);
else
te[pos].getFrame().setVisible(true);
// load defaults, this will be overriden when saved
layers[pos].setFont(te[pos].getFont());
layers[pos].setAlignment(te[pos].getAlignment());
layers[pos].setSize(te[pos].getSize());
layers[pos].setColor(te[pos].getColor()[0], te[pos].getColor()[1], te[pos].getColor()[2]);
layers[pos].setBold(te[pos].isBold());
layers[pos].setItalic(te[pos].isItalic());
layers[pos].setAdjusted(te[pos].isAdjusted());
layers[pos].setWidth(te[pos].getWidth());
layers[pos].setHeight(te[pos].getHeight());
layers[pos].setImage(convertTextToImage(layers[pos].getFile(), pos));
} else
if(layers[pos].getFile().getName().contains("png") ||
layers[pos].getFile().getName().contains("jpg") ||
layers[pos].getFile().getName().contains("jpeg") ||
layers[pos].getFile().getName().contains("bmp")){
layers[pos].setImage(ImageIO.read(layers[pos].getFile()));
layers[pos].setX(0);
layers[pos].setY(0);
layers[pos].setWidth((int) (layers[pos].getImage().getWidth()));
layers[pos].setHeight((int) (layers[pos].getImage().getHeight()));
} else {
JOptionPane.showMessageDialog(null, "txt, png, jpg, and bmp files only!");
layers[pos].reset();
add.setToolTipText("");
if(te[pos] != null) {
te[pos].getFrame().dispose();
te[pos] = null;
}
return;
}
else {
reverseImage(pos);
}
edit.setEnabled(true);
add.setToolTipText(jfc.getSelectedFile().getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
pause = false;
deselect.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
for(int i = 0; i < numberOfLayers; i++) {
layers[i].setSelected(false);
}
}
});
generate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
try {
generatePanel(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
posx.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent arg0) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].isSelected()) {
layers[i].setX((int) posx.getValue());
}
}
}
});
posy.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].isSelected()) {
layers[i].setY((int) posy.getValue());
}
}
}
});
localWidth.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].isSelected())
layers[i].setWidth((int) localWidth.getValue());
}
}
});
localHeight.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if(!ignore) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].isSelected())
layers[i].setHeight((int) localHeight.getValue());
}
} else {
ignore = false;
}
}
});
}
public void addNotify() {
preview.addNotify();
preview.requestFocus();
preview.setFocusable(true);
preview.setVisible(true);
if(thread == null) {
thread = new Thread(this);
preview.addKeyListener(this);
preview.addMouseListener(this);
thread.start();
}
}
private void init() {
image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) image.getGraphics();
running = true;
}
private long redraw() {
long t = System.currentTimeMillis();
if(onTab) {
if(!FileManager.isSleeping())
update();
if(!pause) {
draw();
//drawToScreen();
}
}
return System.currentTimeMillis() - t;
}
public void run() {
init();
while(running) {
long durationMs = redraw();
try {
Thread.sleep(Math.max(0, FPS - durationMs));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void update () {
reupdateImages();
}
private void draw() {
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0; i < layers.length; i++) {
if(layers[i] != null) {
g.drawImage(
layers[i].getImage(),
layers[i].getX(),
layers[i].getY(),
layers[i].getWidth(),
layers[i].getHeight(),
null
);
g.setColor(Color.red);
for(int j = 0; j < layers.length; j++) {
if(layers[j].isSelected())
g.drawRect(
layers[j].getX(),
layers[j].getY(),
layers[j].getWidth(),
layers[j].getHeight()
);
}
}
}
}
private void drawToScreen() {
System.out.println(preview);
System.out.println(preview.getGraphics());
Graphics g2 = preview.getGraphics();
g2.drawImage(image, 0, 0,
WIDTH, HEIGHT,
null);
panelImage = image;
g2.dispose();
}
public BufferedImage generateThumbnail() {
// so draw doesnt interfere
if(!pause) pause = true;
for(int i = 0; i < numberOfLayers; i++) {
layers[i].setSelected(false);
}
draw();
drawToScreen();
int genwidth = Integer.parseInt(width.getText());
int genheight = Integer.parseInt(height.getText());
// manipulate the width and height to specs
BufferedImage resized = new BufferedImage(genwidth, genheight, BufferedImage.TYPE_INT_ARGB);
Graphics g = resized.createGraphics();
g.drawImage(panelImage, 0, 0, genwidth, genheight, null);
g.dispose();
pause = false;
return resized;
}
public void deselect() {
for(int i = 0; i < numberOfLayers; i++) {
layers[i].setSelected(false);
}
}
private void generatePanel(String n) throws IOException {
if(!pause) pause = true;
for(int i = 0; i < numberOfLayers; i++) {
layers[i].setSelected(false);
}
draw();
drawToScreen();
String user = System.getProperty("user.name");
String location = FileManager.getMediaDirectory().replaceAll("/", "\\\\") + "\\";
int genwidth = WIDTH;
int genheight = HEIGHT;
// manipulate the width and height to specs
BufferedImage resized = new BufferedImage(genwidth, genheight, BufferedImage.TYPE_INT_ARGB);
Graphics g = resized.createGraphics();
g.drawImage(panelImage, 0, 0, genwidth, genheight, null);
g.dispose();
//print
File outputfile = null;
if(n == null || n == "")
outputfile = new File(location + "\\test.png");
else
outputfile = new File(n);
pause = false;
ImageIO.write(resized, "png", outputfile);
}
public static void reupdateImagesOverride() {
/* basically, this will update any changes thus
* if a char change happened, it will change ONLY if you are
* using root as your media center
*/
for(int i = 0; i < layers.length; i++) {
if(layers[i] != null && layers[i].getFile() != null && layers[i].getImage() != null) {
try {
if(!layers[i].isReversed()) {
if(layers[i].getFile().getName().contains(".txt")) {
layers[i].setImage(convertTextToImage(layers[i].getFile(), i));
layers[i].setWidth(layers[i].getImage().getWidth());
layers[i].setHeight(layers[i].getImage().getHeight());
} else
layers[i].setImage(ImageIO.read(layers[i].getFile()));
} else {
reverseImage(i);
}
try{
layers[i].collectTimeStamp();
} catch (Exception e2) {
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void reupdateImages() {
/* basically, this will update any changes thus
* if a char change happened, it will change ONLY if you are
* using root as your media center
*/
for(int i = 0; i < layers.length; i++) {
if(layers[i] != null && layers[i].getFile() != null && layers[i].getImage() != null) {
if(layers[i].getFile().lastModified() != layers[i].getTimeStamp()) {
try {
if(!layers[i].isReversed()) {
if(layers[i].getFile().getName().contains(".txt")) {
layers[i].setImage(convertTextToImage(layers[i].getFile(), i));
layers[i].setWidth(layers[i].getImage().getWidth());
layers[i].setHeight(layers[i].getImage().getHeight());
} else
layers[i].setImage(ImageIO.read(layers[i].getFile()));
} else {
reverseImage(i);
}
try{
layers[i].collectTimeStamp();
} catch (Exception e2) {
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// really simple
public static BufferedImage convertTextToImage(File f, int i) {
try {
int tmpy = 0;
int type = Font.PLAIN;
if(layers[i].isBold()) type = Font.BOLD;
if(layers[i].isItalic()) type = type | Font.ITALIC;
layers[i].setFont(te[i].getFont());
layers[i].setAlignment(te[i].getAlignment());
layers[i].setSize(te[i].getSize());
layers[i].setColor(te[i].getColor()[0], te[i].getColor()[1], te[i].getColor()[2]);
layers[i].setBold(te[i].isBold());
layers[i].setItalic(te[i].isItalic());
layers[i].setAdjusted(te[i].isAdjusted());
layers[i].setWidth(te[i].getWidth());
layers[i].setHeight(te[i].getHeight());
// grab width of longest line, if it's multi-line
BufferedImage tmp = new BufferedImage(layers[i].getWidth(), layers[i].getHeight(), BufferedImage.TYPE_INT_ARGB);
BufferedImage actual;
BufferedImage ghetto;
Graphics2D gx = tmp.createGraphics();
gx.setColor(new Color(layers[i].getColor()[0], layers[i].getColor()[1], layers[i].getColor()[2]));
gx.setFont(new Font(layers[i].getFont(), type, layers[i].getSize()));
String line = null;
BufferedReader reader = new BufferedReader(new FileReader(f));
int longest = 0;
while((line = reader.readLine()) != null) {
if(gx.getFontMetrics().stringWidth(line) > longest) {
longest = gx.getFontMetrics().stringWidth(line);
}
}
// check if the image/text is longer then designated width
if(longest > layers[i].getWidth()) {
if(layers[i].isAdjusted()) {
int tmpnum = longest - layers[i].getWidth();
int reduce = 0;
while(tmpnum > sensitivity) {
tmpnum %= sensitivity;
reduce++;
}
for(int z = 0; z < overrideSizes.length; z++) {
if(overrideSizes[z] > layers[i].getSize()) {
if(z - reduce >= 0) {
layers[i].setSize(overrideSizes[z - reduce]);
if(layers[i].getAlignment().equals("right") || layers[i].getAlignment().equals("center")) {
if(z - (reduce + 1) >= 0) layers[i].setSize(overrideSizes[z - (reduce + 1)]);
}
} else {
layers[i].setSize(overrideSizes[0]);
}
break;
}
}
}
// draw to image, ignore controllers wish of width, we will do that later
actual = new BufferedImage(longest, layers[i].getHeight(), BufferedImage.TYPE_INT_ARGB);
gx.dispose();
tmp = null;
gx = actual.createGraphics();
gx.setColor(new Color(te[i].getColor()[0], te[i].getColor()[1], te[i].getColor()[2]));
gx.setFont(new Font(layers[i].getFont(), type, layers[i].getSize()));
reader.close();
reader = new BufferedReader(new FileReader(f));
while((line = reader.readLine()) != null) {
gx.drawString(line,0, (tmpy += gx.getFontMetrics().getHeight()));
}
reader.close();
// now lets resize this
ghetto = new BufferedImage(layers[i].getWidth(), layers[i].getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2x = ghetto.createGraphics();
g2x.drawImage(actual, 0, 0, layers[i].getWidth(), layers[i].getHeight(), null);
g2x.dispose();
return ghetto;
} else {
actual = new BufferedImage(layers[i].getWidth(), layers[i].getHeight(), BufferedImage.TYPE_INT_ARGB);
gx.dispose();
tmp = null;
gx = actual.createGraphics();
gx.setColor(new Color(te[i].getColor()[0], te[i].getColor()[1], te[i].getColor()[2]));
gx.setFont(new Font(layers[i].getFont(), type, layers[i].getSize()));
reader.close();
reader = new BufferedReader(new FileReader(f));
while((line = reader.readLine()) != null) {
if(layers[i].getAlignment().equals("left"))
gx.drawString(line,0, (tmpy += gx.getFontMetrics().getHeight()));
else
if(layers[i].getAlignment().equals("right"))
gx.drawString(line, layers[i].getWidth() - gx.getFontMetrics().stringWidth(line), (tmpy += gx.getFontMetrics().getHeight()));
else
if(layers[i].getAlignment().equals("center"))
gx.drawString(line, (layers[i].getWidth() / 2) - (gx.getFontMetrics().stringWidth(line) / 2), (tmpy += gx.getFontMetrics().getHeight()));
}
reader.close();
return actual;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void reverseImage(int i) {
BufferedImage tmp = new BufferedImage(
layers[i].getImage().getWidth(),
layers[i].getImage().getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics gx = tmp.createGraphics();
try {
if(layers[i].getFile().getName().contains(".txt")) {
layers[i].setImage(convertTextToImage(layers[i].getFile(), i));
} else
layers[i].setImage(ImageIO.read(layers[i].getFile()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
gx.drawImage(
layers[i].getImage(),
layers[i].getImage().getWidth(),
0,
-layers[i].getImage().getWidth(),
layers[i].getImage().getHeight(),
null);
gx.dispose();
layers[i].setImage(tmp);
}
public void mouseClicked(MouseEvent arg0) {
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
// button is being held, scanning layers that match
if(arg0.getButton() == MouseEvent.BUTTON3) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].getFile() != null && layers[i].getImage() != null && layers[i].isSelected()) {
if(layers[i].isReversed()) {
layers[i].setReversed(false);
reupdateImagesOverride();
return;
} else {
layers[i].setReversed(true);
reupdateImagesOverride();
return;
}
}
}
}
if(arg0.getButton() == MouseEvent.BUTTON1) {
for(int i = 0; i < layers.length; i++) {
if(layers[i].isSelected()) {
layers[i].setX(arg0.getX());
layers[i].setY(arg0.getY());
posx.setValue(arg0.getX());
posy.setValue(arg0.getY());
}
}
}
}
public void mouseReleased(MouseEvent arg0) {
}
public void keyPressed(KeyEvent arg0) {
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
public void setOnTab(boolean b) {
onTab = b;
}
}
Don't override addNotify!
A JPanel has a Graphics instance only, and only if it is added to a parent container.
The Graphics instance is built during Component.addNotify() but you overrided it, preventing it to be created.
Maybe try to call super.addNotify() as a quick workaround.
In my snippet code! "checkBoxList" has no of files that are chosen by a file chooser and stored in it
check box "tmp" it has checkboxes for the files!
When i display the files[checkboxlist] in my panel.It comes as unchecked!
After I have the option for tick/untick it.
I have the below code for select/unselect option
I need to know when I display the files!The files should display with checked(tick)
Then I can modify which I can tick/untick.
I stuck on this logic!
[
EDIT: I did and updated answer for this part(see the image).
I Add select/deselectall to the panel(box) and it worked
box.add(chckbxSelectAll);
&& I need&curious to know how to put my selectall checkbox inside my panel
]
public void selectAllMethod() {
Iterator<JCheckBox> i = checkBoxList.iterator();
while (i.hasNext()) {
JCheckBox tmp = i.next();
if (chckbxSelectAll.isSelected()) {
tmp.doClick();
} else {
tmp.setSelected(false);
selectedCounter -= 1;
if (selectedCounter < 0) {
selectedCounter = 0;
}
noOfFileTxt.setText(Integer.toString(selectedCounter));
}
}
}
Here is my button selection method for choosing folder and displaying it in a panel with check box
public void chooseDirectoryFrom() {
String tempStr = null;
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
fileChooser = new JFileChooser();
Font font = new Font("Latha", Font.ITALIC, 10);
fileChooser.setFont(new Font("Latha", Font.PLAIN, 13));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setFont(font);
int returnVal = fileChooser.showOpenDialog(frame);
if (returnVal == JFileChooser.APPROVE_OPTION) {
tempStr = fileChooser.getSelectedFile().getCanonicalPath();
}
if (tempStr != null && !tempStr.trim().equals("")) {
searchBox.setText(tempStr);
// Enable the search button
// btnDisplay.setEnabled(true);
} else {
//btnDisplay.setEnabled(false);
}
} catch (Exception e) {
e.printStackTrace();
}
// public void selectToDisplay() { //disabled btn to display
File sourceFolder = null;
Box box = Box.createVerticalBox();
if (boxList.size() != 0) {
middlePanel.remove(scrollPane);
middlePanel.repaint();
frame.repaint();
boxList = new ArrayList<Box>();
checkBoxList = new ArrayList<JCheckBox>();
fileNamesMap = new HashMap<String, String>();
selectedCounter = 0;
noOfFileTxt.setText(Integer.toString(selectedCounter));
}
sourceFolder = new File(searchBox.getText());
File[] sourceFilesList = sourceFolder.listFiles();
JCheckBox cb1 = null;
for (int i = 0; i < sourceFilesList.length; i++) {
if (sourceFilesList[i].isFile() & sourceFilesList[i].getName().endsWith(".txt")) {
fileNamesMap.put(sourceFilesList[i].getAbsolutePath(), sourceFilesList[i].getName());
cb1 = new JCheckBox(sourceFilesList[i].getAbsolutePath());
cb1.setFont(new Font("Latha", Font.BOLD, 20));
box.add(cb1);
checkBoxList.add(cb1);
cb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (((AbstractButton) e.getSource()).isSelected()) {
selectedCounter += 1;
} else {
selectedCounter -= 1;
if (selectedCounter < 0) {
selectedCounter = 0;
}
}
noOfFileTxt.setText(Integer.toString(selectedCounter));
}
});
}
}
boxList.add(box);
scrollPane = new JScrollPane(box);
scrollPane.setPreferredSize(new Dimension(1050, 350));
scrollPane.setVerticalScrollBarPolicy ( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
middlePanel.add ( scrollPane );
frame.getContentPane().add(middlePanel);
frame.repaint();
frame.revalidate();
}
Here is my image(without selection)!When i load the files in the panel
To answer my own question:
Add checkbox set selected inside the for loop and
outside the checkbox action listener So that it will perform setselected method!.
cb1.setSelected(!cb1.isSelected());
selectedCounter += 1;
noOfFileTxt.setText(Integer.toString(selectedCounter));
selectedCounter += 1; will display the ticked count to the textfield(noOfFileTxt)
Thank you :)
I have this app that runs in eclipse's console and I want it to run in a jframe.
By that I mean that I want it to ask for name, a and b on the JFrame window and then write something on a file.
It works perfectly in the console but I don't know how to run it as a JFrame.
I want it to look something like this(Image made in photoshop):
http://i.imgur.com/rTWko1R.png
And then automaticaly close
Thanks in advance!
some imports...(trying to save space)
public class Test {
public static void main(String[] args) throws FileNotFoundException,IOException {
Scanner s = new Scanner(System.in);
String fileName = new SimpleDateFormat("dd-MM-yyyy_HH-mm'.txt'").format(new Date());
String obs;
String name;
String path = "some path";
int a = 0, b = 0, c = 0, d = 0;
System.out.println("input file name");
name = s.nextLine();
System.out.println("input a");
a = s.nextInt();
System.out.println("input b");
b = s.nextInt();
obs = s.nextLine();
if (a >= 100) {
d = a / 100;
c = a % 100;
b = c;
a = a + d;
}
File file;
if (StringUtils.isBlank(name)) {
file = new File(path + fileName);
} else {
file = new File(path + name + "#" + fileName);
}
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.write("something");
if (StringUtils.isBlank(obs)) {
writer.write("something");
} else {
writer.write(obs + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException ignore) {
}
}
}
}
What you'll need to do
separate out your core logic into a separate method that takes String name, int a, int b, ideally in a separate class - then you can reuse from your console version
Create a basic GUI in a frame with a button to kick off the process
listen to the button press and call core logic method
add validation of inputs if necessary
consider using JFileChooser to allow user to pick the file rather than having to type it in
Example
public class ConsoleInFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ConsoleInFrame().showGui();
}
});
}
public void showGui() {
JFrame frame = new JFrame();
JTextField file = new JTextField(20);
JTextField aText = new JTextField(4);
JTextField bText = new JTextField(4);
JButton go = new JButton("Go");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2));
panel.add(new JLabel("File"));
panel.add(file);
panel.add(new JLabel("a"));
panel.add(aText);
panel.add(new JLabel("b"));
panel.add(bText);
frame.getContentPane().setLayout(
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
frame.getContentPane().add(panel);
frame.getContentPane().add(go);
go.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
process(file.getText(), Integer.parseInt(aText.getText()),
Integer.parseInt(bText.getText()));
}
});
frame.pack();
frame.setVisible(true);
}
public void process(String name, int a, int b) {
String fileName = new SimpleDateFormat("dd-MM-yyyy_HH-mm'.txt'")
.format(new Date());
String obs;
String path = "some path";
int c = 0, d = 0;
if (a >= 100) {
d = a / 100;
c = a % 100;
b = c;
a = a + d;
}
File file;
if (StringUtils.isBlank(name)) {
file = new File(path + fileName);
} else {
file = new File(path + name + "#" + fileName);
}
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.write("something");
if (StringUtils.isBlank(obs)) {
writer.write("something");
} else {
writer.write(obs + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException ignore) {
}
}
}
}
I think you could do something like this:
To do this you have to use JLabel to display text: https://docs.oracle.com/javase/tutorial/uiswing/components/label.html
Then to get the input use JTextField:
https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
And if you want you can use a JButton after you write in the JTextField to save everything to the file:
https://docs.oracle.com/javase/7/docs/api/javax/swing/JButton.html
http://www.javamex.com/tutorials/swing/jbutton.shtml
I have modified code from here for my project.
I want to make a editor that have dynamic text area. Each time I press the enter key, a new text area will create. Sorry, I cannot explain more with English.
Please look my code:
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.Hashtable;
public class SimpleEditor extends JFrame {
int count = 0;
private Action openAction = new SimpleEditor.OpenAction();
private Action saveAction = new SimpleEditor.SaveAction();
//private JTextComponent textComp;
private JTextComponent[] textComp2;
//private Hashtable actionHash = new Hashtable();
public static void main(String[] args) {
SimpleEditor editor = new SimpleEditor();
editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
editor.setVisible(true);
}
// Create an editor.
public SimpleEditor() {
super("Swing Editor");
//textComp = createTextComponent();
coba();
makeActionsPretty();
Container content = getContentPane();
//content.add(textComp, BorderLayout.CENTER);
for (int i = 0; i < count; i++) {
content.add(textComp2[i], BorderLayout.CENTER);
}
content.add(createToolBar(), BorderLayout.NORTH);
setJMenuBar(createMenuBar());
setSize(320, 240);
}
//coba-coba
protected void coba() {
if (count == 0) {
textComp2 = new JTextComponent[1];
count += 1;
} else {
JTextComponent[] texttemp;
texttemp = new JTextComponent[count];
for (int i = 0; i < count; i++) {
texttemp[i] = createTextComponent();
texttemp[i] = textComp2[i];
}
count += 1;
textComp2 = new JTextComponent[count];
for (int i = 0; i < count - 1; i++) {
textComp2[i] = createTextComponent();
textComp2[i] = texttemp[i];
}
}
}
// Create the JTextComponent subclass.
protected JTextComponent createTextComponent() {
JTextArea ta = new JTextArea();
ta.setFont(new Font("Courier New", Font.PLAIN, 12));
ta.setLineWrap(true);
ta.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent ev) {
taKeyPressed(ev);
}
});
return ta;
}
private void taKeyPressed(java.awt.event.KeyEvent ev) {
if (ev.getKeyCode() == 13) {
coba();
}
}
// Add icons and friendly names to actions we care about.
protected void makeActionsPretty() {
Action a;
/*a = textComp.getActionMap().get(DefaultEditorKit.cutAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/cut.gif"));
a.putValue(Action.NAME, "Cut");
a = textComp.getActionMap().get(DefaultEditorKit.copyAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/copy.gif"));
a.putValue(Action.NAME, "Copy");
a = textComp.getActionMap().get(DefaultEditorKit.pasteAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/paste.gif"));
a.putValue(Action.NAME, "Paste");
a = textComp.getActionMap().get(DefaultEditorKit.selectAllAction);
a.putValue(Action.NAME, "Select All");*/
for (int i = 0; i < count; i++) {
a = textComp2[i].getActionMap().get(DefaultEditorKit.cutAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/cut.gif"));
a.putValue(Action.NAME, "Cut");
a = textComp2[i].getActionMap().get(DefaultEditorKit.copyAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/copy.gif"));
a.putValue(Action.NAME, "Copy");
a = textComp2[i].getActionMap().get(DefaultEditorKit.pasteAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/paste.gif"));
a.putValue(Action.NAME, "Paste");
a = textComp2[i].getActionMap().get(DefaultEditorKit.selectAllAction);
a.putValue(Action.NAME, "Select All");
}
}
// Create a simple JToolBar with some buttons.
protected JToolBar createToolBar() {
JToolBar bar = new JToolBar();
// Add simple actions for opening & saving.
bar.add(getOpenAction()).setText("");
bar.add(getSaveAction()).setText("");
bar.addSeparator();
// Add cut/copy/paste buttons.
/*bar.add(textComp.getActionMap().get(DefaultEditorKit.cutAction)).setText("");
bar.add(textComp.getActionMap().get(
DefaultEditorKit.copyAction)).setText("");
bar.add(textComp.getActionMap().get(
DefaultEditorKit.pasteAction)).setText("");*/
for (int i = 0; i < count; i++) {
bar.add(textComp2[i].getActionMap().get(DefaultEditorKit.cutAction)).setText("");
bar.add(textComp2[i].getActionMap().get(
DefaultEditorKit.copyAction)).setText("");
bar.add(textComp2[i].getActionMap().get(
DefaultEditorKit.pasteAction)).setText("");
}
return bar;
}
// Create a JMenuBar with file & edit menus.
protected JMenuBar createMenuBar() {
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
menubar.add(file);
menubar.add(edit);
file.add(getOpenAction());
file.add(getSaveAction());
file.add(new SimpleEditor.ExitAction());
/* edit.add(textComp.getActionMap().get(DefaultEditorKit.cutAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.copyAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.pasteAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.selectAllAction));*/
for (int i = 0; i < count; i++) {
edit.add(textComp2[i].getActionMap().get(DefaultEditorKit.cutAction));
edit.add(textComp2[i].getActionMap().get(DefaultEditorKit.copyAction));
edit.add(textComp2[i].getActionMap().get(DefaultEditorKit.pasteAction));
edit.add(textComp2[i].getActionMap().get(DefaultEditorKit.selectAllAction));
}
return menubar;
}
// Subclass can override to use a different open action.
protected Action getOpenAction() {
return openAction;
}
// Subclass can override to use a different save action.
protected Action getSaveAction() {
return saveAction;
}
//protected JTextComponent getTextComponent() { return textComp; }
// ********** ACTION INNER CLASSES ********** //
// A very simple exit action
public class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
}
public void actionPerformed(ActionEvent ev) {
System.exit(0);
}
}
// An action that opens an existing file
class OpenAction extends AbstractAction {
public OpenAction() {
super("Open", new ImageIcon("icons/open.gif"));
}
// Query user for a filename and attempt to open and read the file into the
// text component.
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(SimpleEditor.this)
!= JFileChooser.APPROVE_OPTION) {
return;
}
File file = chooser.getSelectedFile();
if (file == null) {
return;
}
FileReader reader = null;
try {
reader = new FileReader(file);
//textComp.read(reader, null);
for (int i = 0; i < count; i++) {
textComp2[i].read(reader, null);
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(SimpleEditor.this,
"File Not Found", "ERROR", JOptionPane.ERROR_MESSAGE);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException x) {
}
}
}
}
}
// An action that saves the document to a file
class SaveAction extends AbstractAction {
public SaveAction() {
super("Save", new ImageIcon("icons/save.gif"));
}
// Query user for a filename and attempt to open and write the text
// component’s content to the file.
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
if (chooser.showSaveDialog(SimpleEditor.this)
!= JFileChooser.APPROVE_OPTION) {
return;
}
File file = chooser.getSelectedFile();
if (file == null) {
return;
}
FileWriter writer = null;
try {
writer = new FileWriter(file);
//textComp.write(writer);
for (int i = 0; i < count; i++) {
textComp2[i].write(writer);
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(SimpleEditor.this,
"File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException x) {
}
}
}
}
}
}
But, my code have some error like this:
Exception in thread "main" java.lang.NullPointerException
- at SimpleEditor.makeActionsPretty(SimpleEditor.java:101)
- at SimpleEditor.<init>(SimpleEditor.java:29)
- at SimpleEditor.main(SimpleEditor.java:19)
Can anybody help me as soon as possible?
The array JTextComponent[] has different sizes at different times, but an object in the array defaults to null until you change it:
textComp2[i] = new JTextField("Hello");
First time posting here. Heres my problem: I can't get the saving or loading of my configuration file to work. I am trying to save player names based off how many players specified in my code. Anyone know what is wrong and how to fix?
Config file:
public void savePlayerConfiguration(String key, int value) {
String path = "config.xml";
try {
File file = new File(path);
boolean exists = file.exists();
if (!exists) {
file.createNewFile();
}
OutputStream write = new FileOutputStream(path);
properties.setProperty(key, Integer.toString(value));
properties.storeToXML(write, key);
} catch (Exception e) {
}
}
public void loadPlayerConfiguration(String path) {
try {
InputStream read = new FileInputStream(path);
properties.loadFromXML(read);
String player1 = properties.getProperty("1");
String player2 = properties.getProperty("2");
String player3 = properties.getProperty("3");
String player4 = properties.getProperty("4");
String player5 = properties.getProperty("5");
String player6 = properties.getProperty("6");
read.close();
} catch (FileNotFoundException e) {
savePlayerConfiguration("1", 1);
savePlayerConfiguration("2", 2);
savePlayerConfiguration("3", 3);
savePlayerConfiguration("4", 4);
savePlayerConfiguration("5", 5);
savePlayerConfiguration("6", 6);
loadConfiguration(path);
} catch (IOException e) {
}
}
Options file:
private int width = Main.width;
private int height = Main.height;
private String player1 = "Player1", player2 = "Player2",
player3 = "Player3", player4 = "Player4", player5 = "Player5",
player6 = "Player6";
private String[] playerNames = { player1, player2, player3, player4,
player5, player6 };
private int[] player = { 1, 2, 3, 4, 5, 6 };
private int playerTotal;
private JButton OK;
private JTextField input1, input2, input3, input4, input5, input6;
private JTextField[] playerNameInput = { input1, input2, input3, input4,
input5, input6 };
private JLabel playerName;
private Rectangle rOK, rPlayerAmount;
private Choice playerAmount = new Choice();
Configuration config = new Configuration();
private int button_width = 80;
private int button_height = 40;
JPanel window = new JPanel();
public Database() {
setTitle("Database - Excelteor Launcher");
setSize(new Dimension(width, height));
add(window);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
window.setLayout(null);
drop();
drawButtons();
window.repaint();
}
private void drawButtons() {
OK = new JButton("OK");
rOK = new Rectangle((width - 100), (height - 70), button_width,
button_height);
OK.setBounds(rOK);
window.add(OK);
rPlayerAmount = new Rectangle(30, 130, 80, 25);
playerAmount.setBounds(rPlayerAmount);
playerAmount.add("1");
playerAmount.add("2");
playerAmount.add("3");
playerAmount.add("4");
playerAmount.add("5");
playerAmount.add("6");
playerAmount.select(1);
window.add(playerAmount);
playerName = new JLabel("Player Names:");
playerName.setBounds(30, 110, 120, 20);
window.add(playerName);
for (int i = 0; i < playerTotal; i++) {
playerNameInput[i] = new JTextField();
playerNameInput[i].setBounds(80, 150 + i * 20, 60, 20);
window.add(playerNameInput[i]);
}
OK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
System.out.println("test");
for (int i = 0; i < playerTotal; i++) {
config.savePlayerConfiguration(parsePlayers(), player[i]);
System.out.println(player[i]);
}
}
});
}
private void drop() {
int selection = playerAmount.getSelectedIndex();
if (selection == 0) {
playerTotal = 1;
}
if (selection == 1 || selection == -1) {
playerTotal = 2;
}
if (selection == 2) {
playerTotal = 3;
}
if (selection == 3) {
playerTotal = 4;
}
if (selection == 4) {
playerTotal = 5;
}
if (selection == 5) {
playerTotal = 6;
}
}
private String parsePlayers() {
try {
for (int i = 0; i < playerTotal; i++) {
playerNames[i] = playerNameInput[i].toString();
return playerNames[i];
}
} catch (NumberFormatException e) {
drop();
return player1;
}
return player1;
}
My guess would be that the path of your config.xml, the one being passed into loadPlayerConfiguration(String path), is wrong. Try out the below options for resolving your problem.
Make sure that the 'path' is correct.
Make sure that the 'path' exists using exists() method of File API.
If the path is relative, then confirm whether the path structure has been added onto the
class path. Else, try placing it in the root of your project.
If you still face issues after trying out these steps, then kindly share your project structure.
Cheers,
Madhu.
** EDIT **
#user2399785 : got a clear idea on your problem after going through your config.xml.
<properties>
<comment>javax.swing.JTextField[,80,150,60x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#69ecade2,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]</comment>
<entry key="javax.swing.JTextField[,80,150,60x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#69ecade2,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]">2</entry>
<entry key="javax.swing.JTextField[,80,150,60x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#2904a7cf,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]">2</entry>
</properties>
If you notice your .xml, the KEY contains some kind of a long javax swing detail. But loadPlayerConfiguration(String path) uses properties.getProperty("2") which will return you a VALUE whose KEY is "2" and not vice versa. Since there is no KEY with "2", you are getting the return value as NULL. Try the same code with the KEY as in the .xml and you should be fine.
Cheers,
Madhu.