I have successfully integrated the FCKEditor in swing application.
Now I am trying to achieve that:
1>When the user click in the editing area, an event is to be fired, taking its id.(might use javascript but donot know how to configure in swing).
2>Then that id is to be shown in a jlabel. So, i want to communicate the native editor with swing application.
I tried a lot but without any major success.
special vote of thanks for any help.
As i understand your editor is JPanel.
You can try to add MouseListener to your FCKEditor for the next way:
public class Example extends JFrame {
private JLabel yourLabel;
public Example() {
yourLabel = new JLabel("test");
JPanel component = new JPanel();
component.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
String id = getIDMethod();
//if your editor contains id you can use next code
//String id = ((JPanel)e.getSource()).getIDMethod();
yourLabel.setText(id);
}
});
getContentPane().add(component,BorderLayout.SOUTH);
getContentPane().add(yourLabel,BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String...strings ){
Example e = new Example();
}
protected String getIDMethod() {
return "1";
}
}
Here component - it's your editor. You add MouseListener for that. Next in method mouseReleased you get ID and set it to the label(here yourLabel your target label).
Try this code, I think it's help you
Related
I'm working on an RCP application that's in a transition from a Swing version. So we have a lot of UI components that still need to live in the Swing world during this transition. I'm able to properly place the existing Swing components in AWT-SWT bridge frames.
I've wrapped these Swing components in a JScrollable pane before adding them to the bridge so that I don't have to resize the containing-part when the size of the Swing UI elements change. The code where I place an old Swing component in a part looks like this:
#PostConstruct
public void postConstruct(final Composite parent) {
/* Create embedding composite */
final Frame bridgeFrame;
final Composite embed;
embed = new Composite(parent, SWT.EMBEDDED);
embed.setLayout(new FillLayout());
bridgeFrame = SWT_AWT.new_Frame(embed);
bridgeFrame.setLayout(new BorderLayout());
bridgeFrame.add(
new JScrollPane(getTestPanel()),
BorderLayout.CENTER);
}
My Swing component has a behavior where when the user clicks a button, things that were hidden in the component are made visible, or new UI elements are added to the Swing component. For example:
private JPanel getTestPanel() {
final JPanel output;
final JButton eastBttn, westBttn;
output = new JPanel();
eastBttn = new JButton("East Button");
westBttn = new JButton("West Button");
output.setLayout(new BorderLayout());
output.add(eastBttn, BorderLayout.EAST);
output.add(westBttn, BorderLayout.WEST);
eastBttn.addActionListener(evt -> {
System.out.println("East Button Clicked");
output.add(new JLabel("East Button Clicked"), BorderLayout.CENTER);
});
return output;
}
My problem is, when the elements in the Swing-component change, the parent bridge-frame doesn't properly get rendered.
When the parts are first created, my application looks like this:
After I click on the EastButton it's supposed to add a text label in the center of that bridge frame. However, nothing changes in the application view.
But, when I even begin to resize the containing part-sash a little, the part containing the bridge-frame updates correctly:
What can I do to make the bridge-frame update containing part update automatically?
To test whether this was a repainting issue on the bridge-frame, I had a menu item which would trigger a repaint / revalidate / pack of the bridge-frame, but that didn't solve the issue. I suspect it has something to do with the renderer of the containing part, but have no idea how to go about addressing it.
The same a problem exists in a pure Swing solution:
public static void main(String[] args) {
JFrame bridgeFrame = new JFrame("Test");
bridgeFrame.setSize(400, 400);
bridgeFrame.setLayout(new BorderLayout());
bridgeFrame.add(new JScrollPane(getTestPanel()), BorderLayout.CENTER);
bridgeFrame.setVisible(true);
}
You need to add an output.doLayout() in your event handler.
I eventually got around the problem by attaching a custom ControlListener / ComponentListener to the part containing the bridge. If any changes within the workings of the bridge-frame caused it to resize to beyond the parent, I'd have the listener resize it to fit within the parent thus forcing the scroll-pane to take over.
Here's my listener:
public class BridgeComponetAdapter
extends ComponentAdapter
implements ControlListener {
private final Composite parent;
private final Frame bridgeFrame;
private Point parentSize;
public BridgeComponetAdapter(
final Composite parent,
final Frame bridgeFrame) {
this.parent = parent;
this.bridgeFrame = bridgeFrame;
bridgeFrame.addComponentListener(this);
parent.addControlListener(this);
}
#Override
public void componentResized(final ComponentEvent e) {
System.out.println(e);
if (e.getSource() != bridgeFrame)
return;
final Dimension currentBridgeSize;
currentBridgeSize = bridgeFrame.getSize();
if (currentBridgeSize.getWidth() > parentSize.x
|| currentBridgeSize.getHeight() > parentSize.y) {
bridgeFrame.setSize(parentSize.x, parentSize.y);
}
}
#Override
public void controlMoved(final ControlEvent e) {}
#Override
public void controlResized(final ControlEvent e) {
System.out.println(e);
if (e.getSource() == parent)
parentSize = parent.getSize();
}
}
It's not an elegant solution; I'm still open to other ideas to solve the problem.
I wrote the following code to have a JPopupMenu that allows multiple selection of different items.
The problem is that, as soon as the mouse enters one of the displayed JCheckboxMenuItems, the JPopupMenu gets closed. This issue doesn't occur if I replace JCheckboxMenuItem with, for example, JLabel but, for sure, JLabel doesn't work for my purpose.
Any idea of what could trigger this issue? Any idea of how this problem can be resolved in a better way? I apologize for the newbie question but I'm not a java developer. Thanks in advance for any help.
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedborder(),"Select Layers");
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
for (MyAction layer : layers) {
JCheckBoxMenuItem box = new JCheckBoxMenuItem(layer);
box.setIcon(new SquareIcon(myColor));
panel.add(box);
}
JPopup popup = new JidePopup();
popup.add(panel)
JButton button = new JButton("Layers");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
popup.show(button,0,button.getHeight())
}
});
Thats in the nature of JPopupMenus. They disappear when the invoker component loses the focus. But I found a little trick here.
Create your own class and extend it from JPopupMenu. Then override the setVisible method that it will only forward true to the super class and create an own method that will setVisible of the super class to false.
public class StayOpenPopup extends JPopupMenu{
public void setVisible(boolean visible){
if(visible == true)
super.setVisible(visible);
}
public void disappear() {
super.setVisible(false);
}
}
Then use it like this in your code
[...]
StayOpenPopup popup = new StayOpenPopup();
popup.add(panel);
[...]
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(popup.isVisible())
popup.disappear();
else popup.show(button,0,button.getHeight());
}
});
Now one click on button will show it. And it will stay visible until next click on Button.
I want to call a function when the user pastes text in my JTextArea. Is there any event generated when the text is pasted to the JTextArea and which listener can I use to trigger my function on this event?
One possible solution (and I hope some one has a better one) would be to replace the key binding Action responsible for actually performing the paste operation.
Now, before you do this, the default paste operation is not trivial, instead, I would replace the default paste Action with a proxy, which could call the original, but would allow you to intercept the operation, but not have to re-implement the functionality yourself, for example...
public class ProxyAction extends AbstractAction {
private Action action;
public ProxyAction(Action action) {
this.action = action;
}
#Override
public void actionPerformed(ActionEvent e) {
action.actionPerformed(e);
System.out.println("Paste Occured...");
}
}
Then you would simply need to look up the default Action and replace it...
JTextArea ta = new JTextArea(10, 10);
Action action = ta.getActionMap().get("paste-from-clipboard");
ta.getActionMap().put("paste-from-clipboard", new ProxyAction(action));
The problem here is, this won't tell you if the operation failed or succeeded or what was actually pasted. For that, you could use a DocumentListener, registered before you call the default Action which could record the changes to the document. Obviously, you'd want to deregister this after the default action ;)...
Now, equally, you could just override the paste method of the JTextArea, which equates to about the same thing, but, the first option would be more portable...
As an idea...
Take a look at How to Use Actions and How to Use Key Bindings for more details
you can have something like below, whenever you paste something in the textarea, then 'Pasted!' is printed out on your console. It prints only on paste !
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class TextAreaDemo extends JFrame {
JTextArea _resultArea = new JTextArea(6, 20);
public TextAreaDemo() {
_resultArea.setText("");
JScrollPane scrollingArea = new JScrollPane(_resultArea);
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(scrollingArea, BorderLayout.CENTER);
this.setContentPane(content);
this.setTitle("TextAreaDemo B");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
_resultArea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_V) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
System.out.println("Pasted!");
}
}
#Override
public void keyReleased(KeyEvent e) {
}
});
}
public static void main(String[] args) {
JFrame win = new TextAreaDemo();
win.setVisible(true);
}
}
You can also check out Wrapping Actions which is basically the same suggestion as MadProgrammer except that the WrapperAction will delegate all the methods of the Action to the original Action. This will allow you to pick up the text and Icons associated with the original Action in case you ever want to add your custom Action to a JMenuItem or JButton.
I have a problem with a JDesktopPane, I add JInternalFrame on it and then show it on a JFrame.
The problem is when I try to add another JInternalFrame in execution time.
I use the same method to add the same JInternalFrame but its dosnt shows up.
public class Desktop extends JDesktopPane {
(...)
public void addJInternalFrameBox(JInternalFrameBox jifb) {
this.add(jifb, desktop.CENTER_ALIGNMENT);
this.repaint();
this.validate();
}
}
JInternalFrameBox class:
public class JInternalFrameBox extends JInternalFrame {
(...)
public JInternalFrameBox(Integer id) {
this.id = id;
setUpFrame();
}
public void setUpFrame() {
JLabel lbl = new JLabel("test");
lbl.setVisible(true);
this.add(lbl);
this.setPreferredSize(INTERNAL_FRAME_SIZE);
this.setLocation(100, 100);
this.setIconifiable(true);
this.setClosable(true);
this.pack();
this.setVisible(true);
}
}
jButtonBox the button that open the JInternalFrameBox:
public class jButtonBox extends JButton implements MouseListener {
public void mouseReleased(MouseEvent e) {
JInternalFrameBox jifb = new JInternalFrameBox(id);
jifb.setVisible(true);
Desktop df = Desktop.getInstance();
df.addJInternalFrameBox(jifb);
}
(...)
}
Read the section from the Swing tutorial on How to Use Internal Frames for a working example.
Don't use a JPanel for your desktop, but rather use a JDesktopPane. That's specifically what its for.
you have to set both location and size of the internal frame, as in
setSize(INTERNAL_FRAME_SIZE); // instead of setPref
setLocation(100, 100);
hm ... maybe not (just saw the pack in your code) - no more guessing without an sscce, as others already stated
I am trying to add a hyperlink to a JPanel. I would like to make it's text blue (and underlined) and the link should be selectable (to copy some part of it). So I tried to use JLabel: yes, it allow to write something [awful] like this:
someLabel.setText("<html><font color=\"#0000ff\"><u>http://example.com</u></font></html>");
But unfortunately, JLabel doesn't allow to select any text. I also tried to use JTextField, but in opposite, it doesn't allow to use HTML/CSS in it's fields.
So, Is where exists any way to create a hyperlink (with proper indication) with basic Swing components, which will be allow to select [and copy] part of it, or should I try to use some 3rd party components? Thank you.
You can display HTML content in a non-editable JEditorPane. It's selectable, and you can make the links functional via a HyperlinkListener:
JEditorPane content = new JEditorPane();
content.setContentType("text/html");
content.setEditable(false);
content.setText("<html>Link</html>"));
content.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try {
Desktop.getDesktop().browse(e.getURL().toURI());
} catch (Exception e1) {
Logger.getLogger(getClass()).error(
"Error opening link " + e.getURL(), e1);
}
}
}
});
Here how can you create a JLabel with a hyperlink ,then you can just add it to your Jpanel:
public HyperLinkLabel()
{
JPanel p = new JPanel();
final String strURL = "http://www.yahoo.com";
final JLabel label = new JLabel("<html> click </html>");
final JEditorPane htmlPane = new JEditorPane();
p.add(label);
getContentPane().add(BorderLayout.NORTH, p);
getContentPane().add(BorderLayout.CENTER, new JScrollPane(htmlPane));
setBounds(20,200, 500,500);
label.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
label.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent me) {
label.setCursor(Cursor.getDefaultCursor());
}
public void mouseClicked(MouseEvent me)
{
System.out.println("Clicked on Label...");
try {
htmlPane.setPage(new URL(strURL));
}
catch(Exception e) {
System.out.println(e);
}
}
});
You have to create a custom Jlabel [extend Jlabel] and write a MouseListener for the JLabel.
Your mouse listener must do the job of directing the user to the link when the user clicks on the custom JLabel. The mouse event [basically the method of the MouseListener interface where you have to write the redirecting code] that you are looking for is mouseClicked.