I think I need to restate my question ...
I want to create a SIMPLE form application that edits certain areas of one very specific text file. Though I have some web development experience, I do not want to create a browser based application. Basically I want to give a Desktop application a try and I am looking for some help to get started including suggestions for the language of choice. The application should run on Mac OS X. Besides there's no restriction: Java, Cocoa, Python, even a some interactive shell script would be ok.
If you are interested in the details, continue to read here, but not that my question is not LaTex specific...:
I have an automatically generated report file that contains LaTex Code. Now I want to build a little application that creates a form field for every section and it's header. The document contains only a few hundred lines and the should work the following:
\section{ This is were the header text should go inside the document }
\normalsize{ This is where the normal text should go}
The header / normalsize pairs occur 5-6 times within the document. All I want is a little GUI that allows user to edit between the curly braces without seeing any TeX code. I know that there's LyX and other WYSIWYG approaches to LaTeX – I do not want to reinvent the wheel. I just want to protect the auto-generated code a litte from users and make it a little more comfortable to them.
EDIT:
here's my very first try. I guess I should use PlainDocument instead of directly sending it, but I´ll figure that out, since I got plenty of help from trashgod with the editor / Text Component links. The major problem is to single out the content from \section{} and \normalsize{} stuff. Probably I will some regexp here. I need to get a new text area for every appearance.
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileReader;
import javax.swing.*;
public class basicFrame extends JFrame {
// Declare Variables
JScrollPane bildlauf = new JScrollPane();
JTextArea txtfeld = new JTextArea();
public basicFrame() {
super();
// Main window
setTitle("ReportEditor");
setBackground(Color.LIGHT_GRAY);
// components
try {
File datei = new File("report.Rnw");
FileReader in = new FileReader(datei);
txtfeld.read(in, datei);
in.close();
} catch (Exception e) {
System.out.println("Error !");
}
// setLayout(new GridLayout(2,2));
// Scroll Shizzle
bildlauf.getViewport().add(txtfeld, null);
getContentPane().add(bildlauf, BorderLayout.CENTER);
//txtfeld.setSize(500,680);
//add(txtfeld);
//this.getContentPane().add(txtfeld);
// close
addWindowListener(new WindowLauscher());
}
// event handlers...
protected static final class WindowLauscher extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String[] args) {
//Fesnter erzeugen und anzeigen, die main Sache halt
basicFrame hf = new basicFrame();
hf.setSize(500, 700);
hf.setLocation(100, 100);
hf.setVisible(true);
}
}
Thx in advance for any suggestions!
The TeX on Mac OS X wiki recommends jEdit, which supports plugins. LaTeXTools might be a good start.
Addendum:
I do not want to reinvent the wheel.
All I want to do is create a form application.
Although these goals are somewhat contradictory, you can always parse the file and use a suitable JTextComponent for each editable section. Here's an overview of Using Text Components; see Text Component Features if you want to create your own editor kit, as discussed in Customizing a Text Editor.
Addendum: In addition to the tutorial, you might look at this text field layout example. Also, consider a two-column JTable, which would allow you to cleanly separate your document model from your form view.
Addendum: A few notes on your code.
Class names are usually capitalized, e.g. BasicFrame.
Don't extend JFrame if you're not changing it's behavior; JPanel is a good container for other components, and it can be displayed in a JFrame.
Always buid your GUI on the EDT.
Keep you view and model separate.
Related
I’ve trimmed down the code to only the relevant parts and posted it below. The code works fine. The video plays when you run it but it doesn’t have a seekbar.
public class Screen {
//JFrmae
private JFrame frame;
// Panel which I add the canvas to
private JPanel pVid = new JPanel();
// Canvas
Canvas canvas = new Canvas();
// Embedded Media Player
EmbeddedMediaPlayer emp;
/**
* Create the application.
*/
public Screen() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
//Frame
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//Adding the panel to the frame
frame.getContentPane().add(pVid);
//Adding the canvas to the panel
pVid.add(canvas);
//Setting canvas size
canvas.setSize(715, 402);
//Loading the VLC native library
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "lib");
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
//Initializing the media player
MediaPlayerFactory mpf = new MediaPlayerFactory();
//Misc
emp = mpf.newEmbeddedMediaPlayer(new Win32FullScreenStrategy(frame));
emp.setVideoSurface(mpf.newVideoSurface(canvas));
//Video file name and playing
String file = "video.mp4";
emp.prepareMedia(file);
emp.play();
//pack method
frame.pack();
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Screen window = new Screen();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I’ve looked for an answer online for the last 4 days. Finally I decided to ask here. The official website for vlcj has pictures of a vlcj player they’ve made. There is a seekbar in those pictures. Link to the webpage which has the pics: http://capricasoftware.co.uk/#/projects/vlcj
They have a number of useful tutorials there but they don’t have any instructions for adding the seekbar.
Then I tried downloading their vlcj-player project from their GitHub page. It showed an error because it couldn’t resolve the “com.google.common.collect.ImmutableList” which is supposed to be imported. (At the moment I’m reading about ImmutableList and stuff and see if there’s a way to fix it.) Since I couldn’t figure that out yet, I looked for a class named seekbar or the like in their project. I couldn’t find any.
I also searched elsewhere online for the answer but I just couldn’t find it. I’d really appreciate any help. Thank you.
Edit:
(This edit is in response to the suggestion given to me by #caprica. Read their comment to this question and my reply to that in the comment to understand what I'm talking about here in this edit. I think it'll be useful for others in the future.)
All right, there must have been some problem with my Eclipse or computer. (I’ll type out how I fixed it at the end of this comment.) It’s working now. I’ll type out what I did step by step so that may be it’ll be useful to others in the future to download and install the project.
Download the project.
Import it as a Maven project. (Import > Maven > Existing Maven Project)
Now in Eclipse right click the imported project and select Run As > Maven Install
And that’s it. Now you can just run the project normally. If you don’t know how to run the project, do it like this. Right click the project and select Run As > Java Application and then Select VlcjPlayer – uk.co.caprica.vlcplayer.
Alternatively you can open the class where the main method is and run it. VlcjPlayer class is where the main method is located. The class is in the package uk.co.caprica.vlcplayer.
The problem I faced was that somehow all the necessary files didn’t get downloaded when I ran it as Maven Install. But it worked fine in another computer. Since I knew where the files are downloaded to, I just copied the folder from that PC and put it in the same place in my PC. The folder name is ‘repository’. It’s location is C:\Users\User Name\ .m2. Perhaps Eclipse in this PC has some problem. I’ll reinstall it later to avoid problems in the future.
And this may be useful, the VLC that’s installed in this PC is 64 bit. Not sure if that makes a difference but mentioning it just in case.
Now that the app is working fine I will see the code and see how the seekbar is made. Thanks a lot #caprica for telling me that I should import it as a Maven project. :)
The Basic Controls tutorial shows the essential approach: Add a panel of buttons to the frame and give each button an ActionListener that invokes the relevant media player command. As an example, this notional Rewind button would "skip backwards 10 seconds (-10,000 milliseconds)."
JPanel controlsPane = new JPanel();
JButton rewindButton = new JButton("Rewind");
rewindButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mediaPlayerComponent.getMediaPlayer().skip(-10000);
}
});
controlsPane.add(rewindButton);
frame.add(controlsPane, BorderLayout.SOUTH);
The software design is up to you, but you should at least be aware of
JToolBar, seen here and here.
Action, seen here and cited here.
Timer, seen here as a way to repeat an Action.
All right, guys. I’ve figured out how to do it. I’m not sure how it was done in the official Vlcj project but I’ve figured out my own simple way by learning from the official project.
It just takes a few lines of code. It’s very simple.
These are the steps you have to follow:
Create a JSlider.
To the JSlider, add a mouseMotionListener (‘mouseDragged’ to be exact).
Inside that put in the code which would update the video position based on
the change in the JSlider.
Create a Timer.
Put the code inside it to set the value of the JSlider based on the position
of the video.
And that’s it!
This is the code. It comes inside the initialize() method which you can see in the code I’ve given in the question. (And of course you'll also have to create the JSlider and add it to the panel. I haven't shown the code since it's simple.)
js.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (js.getValue() / 100 < 1) {
emp.setPosition((float) js.getValue() / 100);
}
}
});
Timer timer = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
js.setValue(Math.round(emp.getPosition() * 100));
}
});
timer.start();
Some explanation.
The value you get when you use emp.getPosition always seems to be in decimals. It’s something like 0.1334344 at the start of the video and it’s something like 0.998988 at the end. But the value of JSlider is in int. From 0 to 100. So in the mouseMotionListener added to the JSlider I’ve converted the int value of the JSlider to float by dividing it by 100.
And in the action listener inside the timer I’ve multiplied the value of the video position by 100 and then rounded it off to make it an int value. So that value can be set in the JSlider to make it move in sync with the video.
I’m sure the code is rudimentary and there could be some best practices which I may not have followed. Sorry about that but I’m just getting into java by learning the stuff which I find interesting. Those who are good at java and have used such code in an actual project can comment below with how it can be improved.
I am trying to set the default close operation in NetBeans 8.0.2 (in Ubuntu 14.04 on an older Asus gaming laptop.) My program is very large but uses no JFrame or java.swing components.
I merely need to save some values when the "x" in the lower right corner is clicked (this is one usual way to stop execution of a java program in NetBeans.)
I found suggestions that involved swing & JFrame, but it wasn't clear just where to insert the code:
DefaultApplicationView view = new DefaultApplicationView(this);
javax.swing.JFrame frame = view.getFrame();
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
public void WindowClosing(WindowEvent e){
System.out.println("CLOSING");
}
}
show(view);
I also found a set of instructions that I think I would prefer to use, but the post is old enough that my NetBeans doesn't have the tabs/menu-items referred to:
Set Window to Design Mode by clicking the 'Design' Tab
In the Navigator: Right click the 'JFrame' -> 'Properties'
In the Properties Tab: Set 'defaultCloseOperation' (top of the list) to 'DO_NOTHING'
Select 'Events' Tab
Scroll down to 'windowClosing'
Click on the "..." button on the right of the event to bring up the custom editor
Click 'Add...' and name the handler (i.e. custom function that you want to have execute on click of the 'X', or window close event).
Click 'Ok'
Netbeans now automatically creates the function and takes to you the function body in the source view
Now simply add what you want to do here: eg. dispose(), or system.exit or pintln(), or whatever your heart desires, as long as its JAVA and makes sense to the app.
Then there are a few other possibly relevant posts, but they all explicitly involve JFrame and/or swing. (Am I ignorant of some fact such as "All NetBeans java applications use JFrame", or some such?)
A pared down example of code for what I'm trying to do would be:
public class MyApp{
public static void main(String[] args){
loadMyVariables();
// do some work that changes variables' values
// during this work user clicks the 'x' box to halt execution
// I need then automatically to save the variables' new values
}
// needs to be called by the OS or GUI when execution is halted by user
public static void saveMyVariables{
// here the usual printStream stuff saves some values to a file
System.exit(0);
}
public static void loadMyVariables{
// here the usual Scanner stuff reads some values from a file
}
}
(I need help setting the tags for this, so I'm doing as instructed and asking the community.)
THANKS
I don't understand the wrapping behavior in a JTextPane. If I insert a short text, then a JComponent and then again the short text I can see the inserted stuff in one line if the frame is large enough of course. But if the text is much longer so that it takes several lines the component is always placed in a new line.
I have recognized that after a component has been inserted into a JTextPane its text gets longer by one character. So if a component is considered by a JTextPane as a character why doesn't it behave like a character? May it depend on the java version? I use Java(TM) SE Runtime Environment (build 1.7.0-b147)
Below is my code (instantiate the variable currentText with shortText/longText to reproduce the mentioned behavior):
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
JTextPane textPane = new JTextPane();
textPane.setContentType("text/html");
String shortText = "one two three four five six seven";
String longText = "A text component that can be marked up with attributes that are represented graphically. You can find how-to information and examples of using text panes in Using Text Components, a section in The Java Tutorial. This component models paragraphs that are composed of runs of character level attributes. Each paragraph may have a logical style attached to it which contains the default attributes to use if not overridden by attributes set on the paragraph or character run. Components and images may be embedded in the flow of text.";
String currentText = shortText;
try {
// insert text before the component
textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText,
new SimpleAttributeSet());
textPane.setSelectionStart(textPane.getDocument().getLength());
textPane.setSelectionEnd(textPane.getDocument().getLength());
JComboBox component = new JComboBox();
component.setMaximumSize(component.getPreferredSize());
textPane.insertComponent(component);
// insert text after the component
textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText,
new SimpleAttributeSet());
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
textPane.setEditable(false);
frame.add(new JScrollPane(textPane));
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
That strange behavior seems to happen due to the content type you set. Try removing this line:
textPane.setContentType ( "text/html" );
and you will see that everything works fine after that. I am not sure why it happens - might be either some rendering bug or just an intended behavior.
P.S. I don't think that using Swing components inside text pane (whatever the reason is) is a good option. But that is just my opinion...
When a user clicks a JButton in my Java-Swing application, a string is returned from a method and the user then needs to be able to read the string (somehow). The JButton is within a JPanel. My first thought was to create an 'alert' dialogue (thinking this would be easy), I tried to follow this example that looked easy: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/DialogExample.htm
I have not yet been able to confirm if this works because I do not know how to import the libraries into eclipse. For example import org.eclipse.swt.SWT; gives the error "... cannot be resolved".
So one possible solution is how to import in Eclipse. Another possible solution is to dynamically change the text within the JPanel somehow.
As Ben mentioned in his comment. I would set a jLabel with a blank text to start. Then, when you click your button that triggers the method, simply tack on:
label.setText(value);
Alternatively you could use another pane to popup and display the message.
If you're talking about Swing, an easy solution is to pop a message box with the string:
button.addActionListener(new ActionListener {
public void actionPerformed(ActionEvent e) {
String message = methodThatReturnsYourString();
JOptionPane.showMessageDialog(null, message);
}
}
In this link you will find the information u require in order to add the library and import it:
http://www.eclipsepluginsite.com/swt.html
as well I would not mix SWT with swing and I would stick to swing you can set the label on the event of your button
button.addActionListener(new ActionListener {
public void actionPerformed(ActionEvent e) {
String message = "Test String";
labelMessage.setText(message );
}
}
GWT FileUpload comes as a widget that produces so that one can upload a file during form submit (at least it's how I understand it :) ) What I want to do is to make it a better-looking and get rid of standard "Browse..." button.
Since I don't have good GWT experience (and no JavaScript), I looked for existing solutions and found quite a good project - gwtupload. It's good, but I realized I'd love to have my own miniature version (and also, I was curious about how it works). So I browsed through code and tried to extract the magic part. I realized that GWT FileInput is used, but it's not shown, and Button clicks are delegated to this FileInput. The code I tried to extract (only the part that delegates the click) after reviewing sources of gwtupload contains this tricky elem.click() JSNI:
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUpload upload = new FileUpload();
AbsolutePanel container = new AbsolutePanel();
// container.add(upload);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
But this seems not to work: clicking on 'My Browse..' results in no effect (just in case I also tried running with un-commented container.add(upload) line) . Could you please help me in understanding what's wrong/missing in this code sample?
Thank you in advance.
P.S. I know that I have to place it on the FormPanel, and I know the rest about how to perform the actual submit/handling in Servlet; the only thing I want to do is this kind of decoration.
Since I have not received any answers, I had to have more investigation of this issue, so I performed a deeper code analysis of gwtupload project in order to understand how GWT FileUpload (which gets transformed into ) can be decorated.
It turned out that element.click() will only work in browsers which support #click() method (IE, Chrome, Safari). Actually, Manuel Carrasco Moñino - project author - mentions it within comments. There's second approach (for Firefox & Opera) that uses hack when FileInput is placed on transparent panel, which however is placed over some decorated button (using absolute positioning); comment by Manuel:
When the user puts his mouse over the button and clicks on it, what really happens is that the user clicks on the transparent file input showing the choose file dialog.
After that, the main work is correctly applying style attributes to elements.
Thus, there are two implementations of custom file upload component, and GWT deferred binding is used to instantiate them depending on Browser.
As for example I mention in my question, there're few fixes ("upload" has to be added to to the container, and it can be set to #setVisible(false)):
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUploadWithMouseEvents upload = new FileUploadWithMouseEvents();
AbsolutePanel container = new AbsolutePanel();
container.add(upload);
upload.setVisible(false);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
This example works fine in IE8.
P.S. Thanks to Manuel for his great library :)