Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - zonahurbana

#1
Programación General / Procesos en paralelo
30 Agosto 2016, 05:44 AM
¿Qué pasa cuando 2 procesos acceden en paralelo a la misma posición de memoria e intentan modificarla?
Me parece que habían formas para resolver estos conflictos, pero de forma resumida, ¿cuál sería una respuesta concisa en una entrevista de trabajo?
#2
Seguridad / Consulta sobre HTTPS y JWT
17 Agosto 2016, 03:28 AM
Hola.
Debo implementar una api en Laravel, que será usada en una app Android.
Ya he hecho esto antes, pero nunca me preocupé realmente por si la api era segura.

Lo primero que debo hacer es el login. Para ello he leído que usar Json Web Tokens en una forma válida de hacerlo.
JWT consiste en enviar las credenciales haciendo una petición a la api. La api verifica los datos, genera un token, y lo devuelve como respuesta. La app Android almacenará este token y lo usará en el header de las peticiones siguientes.

Mi pregunta es, ¿por qué se aplica un cifrado sobre el token y no se envían las credenciales en cada petición?
Si el token es cifrado debe ser porque se puede acceder a él a través de un análisis en el tráfico de red. En todo caso, la primera petición, cuando el token aun no se ha generado, ¿está totalmente expuesta?

Leí acerca de "man-in-the-middle", pero no sé si el concepto se aplique exactamente en este caso. Según leí, esto puede evitarse usando HTTPS.
¿HTTPS protege las peticiones que se hagan sobre una página determinada sin importar quién sea el cliente (web, app móvil)?

Si esta protección es cierta, ¿debería preocuparme en conseguir HTTPS para el dominio donde funcionará la api más que por aplicar JWT?
Es decir, podría aplicarse JWT adicionalmente, pero si HTTPS ofrece un cifrado a las peticiones, teóricamente ya no tendría que usar tokens, verdad?
#3
Un "cliente" me ha enviado un proyecto que compró por internet, es un script para editar imágenes desde web, añadirle texto, etc.

Él quiere que haga una modificación en particular, pero cuando descargo los archivos, obtengo una amenaza en el avast al intentar abrir el index.html

Es muy extraño, la primera vez que veo algo de este tipo.
Incluso, si no intento abrirlo en el chrome y solo ver el código con block de notas, no me permite, ni en sublime ni en phpstorm.
También quise subirlo a un analizador online pero al seleccionarlo me dice que no se pudo porque se detectó virus y se borra siempre el archivo.

¿Debería desactivar mi avast?
Me parece extraño que un html esté infectado... no es siquiera un excel... y por ver en block de notas su contenido, qué podría pasar?

Dejo el enlace a MEGA que me pasó esa persona por si quieren descargarlo.
Se baja normal pero no se puede visualizar el index.html (al menos no puedo yo que tengo avast). Se borra el archivo y no pasa a mayores. Todos los demás files se ven bien, y el código parece no tener nada extraño... solo ese HTML

https://mega.nz/#!mMpVGJgC!lLOJA_K9tPggS1oUFjaCMBQ5T_UL-EOtZRDBdH-61dQ

Nota Mod: Posible Malware.

Gracias de antemano, espero puedan ayudarme.
#4
.NET (C#, VB.NET, ASP) / API para manipular VS
26 Julio 2015, 19:09 PM
Me pregunto si existe alguna librería para manejar comandos sobre Visual Studio.

Hace poco me enteré de la existencia de un programa llamado "asistente Jarvis" que a través de reconocimiento de voz permite que ejecutemos comandos hablando por el micro... a cambio sucede alguna acción y/o recibimos además una "respuesta hablada".

Estuve buscando un poco y según veo es relativamente sencillo (en comparación a cómo creí yo que sería) crear un programa con reconocimiento de voz usando System.Speech.

Entonces, quisiera crear un asistente que nos ayude en el desarrollo.

El programa que menciono permite hacer búsquedas en los buscadores más conocidos, abrir carpetas (hay que agregarlas manualmente), ejecutar programas (también hay que agregarlos seleccionando el .exe), escribe lo que le dictamos, lee lo que le indicamos, etcétera.

Pero lo que yo quiero conseguir es algo como lo siguiente:
Citar- "Usar reconocimiento del lenguaje C#"
* "Reconociendo lenguaje C#"

- "Ir a la línea 36"
* "Estamos en la línea 36"

- "Crear un método estatíco que devuelva un objeto de tipo String"
* "Método estático creado"

- "Ir a la clase FormPrincipal"
* "Estamos en la clase FormPrincipal"

- "Ubicar el método actualizarTabla"
* "Método ubicado"

- "Copiar el contenido"
* "Se ha copiado el contenido del método actualizarTabla"

Y bueno, sería de agregar un diccionario para poder indicarle que defina variables, cree clases, objetos, y que el asistente conozca la sintaxis según el lenguaje que se le indique.

La verdad es que, programar sin usar el teclado/mouse sería excelente.
De hecho, tendríamos más tiempo para dedicarnos en pensar la lógica que escribir o tener que ubicarnos en una pos determinada. Para mí resulta cansado tener que ubicar una pestaña o abrir una clase. Es decir, es una acción pequeña pero haciéndolo tantas veces, el tiempo total consumido debe ser mucho  ;D

He buscado comandos de visual studio, y hay algunas combinaciones que permiten ir a la siguiente pestaña. Esto creo que lo puedo hacer, haciendo que se "presionen ciertas teclas".

Pero, por ejemplo, si quiero ubicar una clase (entre los archivos de mi solución), la verdad es que no tengo idea.

Por favor, espero puedan ayudarme...  ;-)
#5
La verdad es que estoy obteniendo un error que no tiene sentido alguno.

VS me indica que no es posible convertir un DataRow en un DataTable... cuando en realidad no sé de dónde obtiene la idea de "DataRow" si nunca he usado dicha clase.


Aquí está el método listar que devuelve un DataTable


Dicho DataTable viene desde mi clase Conexión


He limpiado la solución y vuelto a generar, pero nada.
El programa no se puede ejecutar porque salta dicho error de compilación.

¿A qué podría deberse? ¿Es un fallo del VS?
#6
La verdad es que tengo un poco de experiencia usando Java y C#, y aunque aún no me acostumbro a la sintaxis de VB, lo siguiente me parece muy extraño.

1. La imagen siguiente muestra la instanciación de un objeto de mi clase Conexion (la estoy creando con la intención de facilitarme las cosas para futuras conexiones).
Le indico el nombre de la BD e invoco un método para hacer uso de dicho objeto.

(En el constructor creo un SqlConnection y un SqlAdapter en base a tal conexión)

2. Este es el método invocado desde lo que se muestra en la imagen 1 (que sería el evento Load de mi formulario). Y donde aparece la flecha es a donde aparentemente nunca se llega. El MessageBox nunca muestra el número 2. Antes de invocar a consultar estaba un MessageBox que mostraba el "1" y sí que sale, pero no el "2".


3. Este método consultar está dentro de mi clase Conexion. Se muestra "1a" y "1b" pero "1c" jamás se muestra. Mientras se muestran estos MessageBox el formulario (que es para editar/agregar productos) no se muestra (solo se ve el form principal desde el que se invoca).
Luego de que acepto el mensaje "1b", aparece el dichoso formulario y sin congelarse funciona bien. ¡ ¿Pero qué pasó con "1c" y "2" y "3"? !


Espero puedan darme una ayuda.
Gracias.
#7
Hola.

Estudio ingeniería de sistemas y he llevado ya varios cursos, pero todo es superficial, ya que (como dicen algunos docentes) nos enseñan diversos ámbitos sin centrarse en uno en particular.

Estoy llevando un curso llamado "comunicación de datos".
En la primera unidad tuve que presentar un programa en C# que permita enviar tramas de 1 PC a otra, conectadas a través del puerto serial.

El enunciado pedía que una de las PC conectadas pueda enviar 1 archivo a la otra, y mientras esto sucedía puedan enviarse mensajes en un chat. Para ello usé una clase SerialPort. Pero adicionalmente incluí algo más, que puedan enviarse varios archivos en ambos sentidos y que aún así puedan comunicarse, además de mostrar el porcentaje de avance. También agregué que cuando uno enviaba un archivo el otro debía aceptar para recibirlo, de ser así el emisor se enteraba e iniciaba el envío. Usé las ventanas que son para abrir y guardar archivos. En otras palabras, me tomó algo de tiempo comprender el funcionamiento de hilos, eventos y delegados (aún no los conozco al 100% pero les he dado ya un uso), y todo esto a fin de no rendir el examen teórico jeje.

A todo esto, se me hizo bastante extraño que yo haya tenido que programar la aceptación del archivo.
Es decir, si no lo hacía, en la computadora destino, con solo abrir el programa se podrían estar creando varios archivos vacíos y recibiendo información de la otra PC, sin que se entere (él solo ha abierto el programa).

Yo tuve que definir "cabeceras" para las tramas y reconocer qué tipo de información se estaba recibiendo, si era una petición para que acepte un archivo, si era la extensión del archivo luego de haber aceptado, si era contenido del archivo o si era un mensaje.

Ahora que hemos avanzado a la 2da unidad hemos empezado a revisar un poco sobre el envío de tramas por red, esto es con sockets, pero en este caso estamos definiendo un protocolo y lo que nos llega es solo el contenido, mas no se tiene acceso a la cabecera que define el protocolo. En lo que entendí estamos usando el protocolo tcp/ip y como hay varios niveles en una comunicación (son 7 niveles OSI, como red, transporte, etc) se tiene una cabecera ya definida en cada nivel del protocolo, y se decodifica en el momento en que llega.

Mi pregunta es, ¿cómo puedo capturar la trama completa que viene (más allá de recubir la información central)?
Según lo que entendí, si se trata de una comunic multipunto donde mi PC es un nodo, entonces mi PC recibe una serie de tramas bajo el protocolo tcp/ip, pero simplemente "pasa de largo" ya que el destino no era mi PC sino otra. ¿Cómo puedo capturar esa información completa y guardarla/mostrarla?

Supuestamente estaría codificada y no entendería su contenido, pero sería el primer paso para comprender el contenido y "poder hacer algo con ello". ¿Verdad?

Gracias por su atención.
#8
Java / Consulta sobre ventanas Undecorated
3 Septiembre 2014, 17:23 PM
Lo que deseo conseguir es que mi JDialog no presente los botones de maximizar, minimizar, cerrar. Ello lo logré fijando dicho JDialog como undecorated, sin embargo, ahora no es posible mover la ventana.

¿Hay forma de mover el JDialog cuando éste es undecorated?
Tal vez deba agregar un botón que al darle clic permita desplazar la ventana, ¿pero cómo podría hacer ello?

He estado leyendo un poco sobre los Look&Feel y he visto ejemplos en que se modifican los botones u otros componentes, pero de una manera muy superficial y no encontré uno en que se modifique a detalle el marco superior de la ventana. Solo deseo quitar los botones, pero que el marco permanezca para que sea posible cambiar la posición (de ser posible reducir el tamaño del marco).

La idea es que el usuario no cierre la ventana (que no vea el botón de cerrar, maximizar específicamente), pero que sí pueda moverla.

Gracias por leer, y espero que por favor puedan darme alguna sugerencia.
#9
Conozco C++ y Java a un nivel intermedio pero referente a páginas web no he revisado mucho aún... sin embargo, por curiosidad quería ejecutar algunas líneas de código PHP e instalé en mi ordenador el servidor WampServer. He visto que algunos usan Xammp en su lugar.

Desde que lo instalé puedo acceder a localhost para ver las páginas PHP de modo local y además a phpMyAdmin para consultar algunas bases de datos que estaban vinculadas con mis programas en Java.

Las bases de datos las he creado usando la herramienta Workbench donde es posible definir las tablas, sus columnas y las relaciones de modo gráfico y luego generar un código SQL que finalmente era importado al phpMyAdmin. Y aquí está mi duda.

phpMyAdmin es solo un gestor de BD pero no es necesario que importe el SQL allí para que la BD sea creada, ¿verdad? Porque me parece haber visto que desde el Workbench también es posible conectarse a la BD e importar el SQL correspondiente. Eso quiere decir que al fin y al cabo las bases de datos son también archivos, ¿verdad? Solo que guardan datos de un modo más ordenado y permiten operaciones de búsqueda. Esto último es lo que identifico como ventaja, por la cual usar BD en vez de guardar los datos en archivos.

Entonces la pregunta es... si tengo un programa con BD ya totalmente funcional y quiero dejar tal sistema listo para usarse en un pequeño negocio de venta, ¿cómo podría crear un instalador que cree la BD una única vez y que descomprima el .jar en una ruta del disco C? porque no es necesario instalar un servidor como Wamp, ¿verdad?
#10
ASM / Consulta sobre condiciones y saltos
17 Mayo 2014, 05:40 AM
Bueno, luego de haber aprendido un poco más acerca de las instrucciones y direccionamiento conseguí escribir un programa para graficar una circunferencia y hacer que esta se desplace... y funcionaba perfectamente hacia la derecha e izquierda.
El problema es que luego de agregar desplazamientos hacia otros lados me apareció este error:
CitarRelative jump out of range by 002Bh bytes

Conseguí solucionarlo agregando saltos intermedios pero el programa no está tan claro como antes justamente por agregar esos "medios saltos", ¿existirá otra forma de manejar ese error?
Tal vez alguien quiera recibir mi código para ayudarme a ver cómo evitar saltos tan largos :S

Gracias de antemano.
#11
ASM / Insertar $ en un LABEL BYTE
1 Mayo 2014, 16:21 PM
En el DATA SEGMENT se tiene la declaración de algunas cadenas y además:
Código (asm) [Seleccionar]
CADENA LABEL  BYTE
TOTAL DB 21
ACTUAL DB ?
CADE DB 21 DUP(?)

; Escribimos 21 ya que el ENTER ocupa un byte.
DOLAR DB "$"

CADINV DB 21 DUP(?),"$"

CADINV es donde pretendo guardar la cadena ingresada luego de ser invertida.
De momento el programa lee una cadena en un LABEL BYTE y muestra un mensaje diciendo "LA CADENA INGRESADA ES: " y la cadena misma de forma correcta.

El problema ocurre cuando se ingresan menos de 20 caracteres. Ya que hay un retorno de carro que hace que el cursor regrese al inicio de esa línea y continue escribiendo los caracteres faltantes (que no fueron ingresados) y borre parte del mensaje, pudiendo quedar por ejemplo "ENA INGRESADA ES: ".

En mis primeras clases vimos un poco acerca del debug.exe donde agregábamos instrucciones una por una. Y como en el foro me explicaron que podía usarse para analizar los programas, intenté hacerlo y allí fue cuando supe que el caracter era el retorno de carro.

Lo que quiero hacer es usar el byte llamado ACTUAL (en realidad no sé cómo referirme a los DB, ¿decir que son variables?) y allí mismo asignar el $, es decir, ya no esperar necesariamente al final de los 21 caracteres.
Pero según estuve viendo ACTUAL guarda un número, por ejemplo 11 y no un desplazamiento.

Entonces intenté esto:
Código (asm) [Seleccionar]
CALL INGRESO    ; Lectura de cadena
LEA BX,CADENA
ADD BL,ACTUAL
MOV [BX],"$"


Se llama al procedimiento para leer la cadena, luego pretendí asignar a BX el desplazamiento del LABEL BYTE y sumarle la posición actual para luego a ese desplazamiento asignarle "$". Pero no funciona.

Por favor, espero que puedan ayudarme. Mi principal problema es que no reconozco aún muy bien qué es lo que se asgina y puede asignarse entre los registros y las variables.

Gracias de antemano.
#12
ASM / Pregunta simple sobre registros
19 Abril 2014, 17:55 PM
Acerca de los registros de 16 bits de "uso general": AX, BX, CX, DX
Y también los demás, como: CS, DS, SS, ES...

¿Existen en general y son usados por cada programa que se ejecuta? ¿O cada programa tiene una sección de memoria reservada sólo para sí mismo y se le asignan sus correspondientes registros?

Uso Windows 7 y usando DosBox puedo acceder a la aplicación debug.exe pero no entiendo qué es lo que sucede cuando modifico los valores de estos registros... quiere decir que si estoy usando un programa el programa modificará los valores de los punteros para ejecutar su código correspondiente? y por tanto habría error si ejecuto un programa y simultáneamente cambio los valores de los segmentos...

Y si cada programa tiene su respectiva segmentación, entonces qué es lo que modifico con el debug? los registros asignados para el programa "debug"?

La verdad me resulta muy confuso. Por favor espero que puedan ayudarme a entender mejor este tema.
#13
Recuerdo que para insertar código HTML en una página se tenía que cambiar los paréntesis angulares <, > por caracteres un tanto extraños, para que no sean asumidos como tal en el código si no que aparezcan escritos en la página misma.

¿Necesito hacer esto siempre con el código?
Tal vez conozcan alguna mejor manera de hacerlo.

He buscado en google pero las entradas no son justamente lo que pregunto.
Gracias de antemano.
#14
ASM / Consulta sobre máquinas virtuales
9 Abril 2014, 00:36 AM
Estoy llevando un curso sobre "Procesadores digitales" y el profesor nos comentó que en la 1ra unidad veríamos un poco del lenguaje ensamblador (que creo que es ASM, de assembler, y por ello publico acá).

Bueno, nos dijo que no es posible ejecutar el Debug en Windows 7, ya que sólo hasta Windows XP es posible usarlo, y que deberíamos instalar una máquina virtual en la que tengamos XP para poder seguir las clases.

El punto es que, según me comentaron, si instalo una máquina virtual voy a tener que compartir recursos a ese 2do sistema operativo y mi computadora estaría funcionando a una velocidad menor. ¿Qué tan cierto es esto? ¿La velocidad se reduce a la mitad?

Por otro lado, hoy en la primera clase, usamos computadoras con Windows 7 y allí mismo ejecutamos el Debug. El profesor dijo que instalaron una aplicación que hacía eso posible (y no se trataba de una máquina virtual). ¿Cómo podría hacer eso?
Cuando le preguntaban decía que teníamos que instalar una máquina virtual... nadie preguntó sobre esa aplicación que permitía ejecutar Debug sin una máquina virtual (por alguna razón no lo decía). Iba a preguntarle yo pero la verdad es que por falta de tiempo preferí no interrumpir y tratar de entender lo tanto que él trataba de explicar... y luego tuve que salir rápidamente hacia mi clase siguiente.

Entonces tal vez alguien conozca acerca de esto y pueda ayudarme. Gracias de antemano.

EDIT: He estado buscando por internet y veo que existe una aplicación "WinDbg" pero según la descripción permite encontrar errores en programas. Creo que eso es más complejo. Al menos tengo entendido que nosotros sólo ejecutaremos algunas instrucciones al procesador directamente. Además una captura de pantalla muestra un programa con interfaz gráfica, y el Debug debería ser solo consola.
#15
En C++ no llegué a usar mucho clases y objetos, más que todo usaba funciones que se llamaban entre sí o que eran recursivas.

En Java, digamos que ya he usado la POO como tal. Entonces, en muchas ocasiones pude reutilizar código sin tantas complicaciones, a través de herencia y polimorfismo. Incluso creo que comencé a utilizar mejor los métodos, y a crearlos siempre que fuese conveniente.

Ahora me encuentro con una situación un tanto particular, en la que me he detenido por pensar qué es lo mejor que puede hacerse.

Tengo un método agregarProducto en una clase que gestiona un listado del mismo.
Aquí se tienen las restricciones para los atributos ingresados. Si hubo error, el producto no se agrega al listado y se devuelve una advertencia como String. Si no hubo error, el producto es agregado y se devuelve null.

Ahora he querido agregar un método modificarProducto. A éste se le pasa la posición del producto a modificar (existe un método que devuelve la posición de un producto buscándolo por su código) y los atributos que deben asignarse.

Creo que lo más correcto es copiar el código de agregarProducto pero cambiar las líneas en las que se agrega... es decir, cambiar el add por un set (el listado es un ArrayList). Así, modificar también devuelve una advertencia, y si no la hay, devuelve null.

Pero me pareció extraño copiar el código ya que no lo hacía por un buen tiempo, y pensé en lo siguiente:

1. Podría hacer que agregarProducto llame a modificarProducto y que en vez de pasarle una posición intermedia, le pase la última posición+1. Pero podría darse el caso de que no se haya reservado memoria para tal posición aún.

2. Podría hacer lo anterior pero en el método modificarProducto evaluar si la posición es mayor a la longitud actual del ArrayList. De ser así agregar (usar add), sino, modificar (usar set).

3. Que agregarProducto se mantenga tal cual pero modificarProducto llame a agregarProducto. En caso de que se haya agregado, pasar ese objeto a la posición que se quiere modificar y luego eliminar la última posición. Así modificar ya no tiene el mismo código (no tendría que copiarlo) y se modificaría la posición deseada con datos correctos. Lo malo es que estoy haciendo operaciones adicionales.

A fin de cuentas, es mejor a veces copiar el código que tratar de no hacerlo y complicarse en vano, ¿verdad?
Además, más líneas de código pueden estar más optimizadas que otras muy pocas.

A veces me pasa esto, que me lío en vano, pudiendo simplemente avanzar con el programa y no detenerme a pensarlo tanto.

Edit: Muchas gracias por su interés, espero que puedan ayudarme un poco comentando cómo creen que es conveniente hacerlo.
#16
Java / Consulta sobre JMenuBar
13 Marzo 2014, 17:29 PM
A este componente le puedo agregar varios JMenu y a cada uno de estos sus correspondientes JMenuItem, pero si lo que deseo es agregarle botones al JMenuBar, ¿cómo puedo hacerlo?
Porque recuerdo haber visto un menú que además de tener opciones escritas en texto presentaba botones a modo de imágenes pequeñas (tampoco tan pequeñas como íconos, sino de 60px aproximadamente).

Gracias de antemano, espero que puedan ayudarme.
#17
Java / Acerca de JFrame usando Netbeans
9 Febrero 2014, 19:53 PM
He creado un programa con interfaz gráfica usando Netbeans pero sin usar el asistente para crear GUI.
En dicho programa (escrito a puro código) he usado colores que ya vienen predefinidos... como CYAN, BLACK, WHITE de clase Color. Pero recordé que hay otros tipos de colores que también están predefinidos, y como no sé cómo agregarlos, he creado un JFrame Form con el asistente para asignar tal color, luego ver el código y copiarlo a mi programa que está sin el asistente.

Lo malo es que, lo que se muestra en la vista de diseño no es lo mismo a lo que se ejecuta:



¿A qué podría deberse?

He buscado en el código, y lo que se ha autogenerado es:
jPanel1.setBackground(javax.swing.UIManager.getDefaults().getColor("nb.output.selectionBackground"));
#18
Java / Cómo crear este tipo de tablas
8 Febrero 2014, 01:10 AM
Creo que es bastante extenso el código para usar títulos en columnas y filas, por eso estaba pensando en usar un GridLayout en vez de tablas.
Pero no estoy muy seguro de cómo hacer esas particiones. Como se observa en la imagen, cada celda presenta dos datos, sólo que el espacio no está igual de dividido.
#19
Java / Sobre lectura de varios datos a la vez
7 Febrero 2014, 00:27 AM
El método showInputDialog de JOptionPane permite leer un único dato. Si son varios usualmente uso un bucle, pero quiero leer datos de a pares porque están relacionados. Y si se lee por separado, podría confundir al usuario.
Estaba creando una clase que herede JFrame y pregunte todas las preguntas que yo le indique, es decir, presente varios JLabel y JTextField según la cantidad de preguntas.
El punto es que, no sé cómo hacer para que devuelva los datos leídos luego de presionar un botón que incluí en el mismo JFrame hacia otro programa que también se está ejecutando y se encargó de crearlo :S
#20
Java / Consulta sobre JTable
4 Febrero 2014, 14:16 PM
He visto que en los JTable es posible agregar datos en las celdas o bloquearlas, pero que aparte de eso, aparecen títulos en las columnas (con un fondo distinto al de las celdas). ¿Es posible agregar además títulos a cada fila?
Es decir, es como crear un cuadro de doble entrada. Quisiera lograr que los datos de calda celda se correspondan con un título de fila (origen) y un título de columna (destino) para organizar datos.
#21
Java / Crear proyecto Swing usando Netbeans
4 Febrero 2014, 14:12 PM
Estuve practicando un poco de interfaces gráficas en Java sin usar el asistente de Netbeans que trae consigo una vista de diseño (en la que puede podemos arrastrar componentes y hacer que se genere el código correspondiente).
Pero ahora, que he querido crear un proyecto de tipo Swing, veo que no aparece entre las opciones para ser elegido. Hace tiempo recuerdo que estaba allí. ¿Creen que algo tiene que ver el haber instalado un nuevo estilo al editor de texto?
#22
Java / Consulta sobre un ejercicio de clases
23 Noviembre 2013, 22:40 PM
En síntesis, lo que el enunciado me pide es crear clases o interfaces para estas entidades: personas, empleados, médicos y pacientes.

Los empleados pueden contratarse de 2 formas (por Planilla o de forma Eventual), entonces haré que 2 clases hereden de Empleado. Pero además me indica que un Médico es un tipo especial de Empleado.
¿Debería crear una clase Médico que herede también de Empleado, al mismo nivel que las clases que catalogan a los empleados según la forma en que fueron contratados? Podría considerarlo así para simplificar, porque no menciona de que un Médico pueda contratarse por esas modalidades. Además dice que los empleados son personal administrativo y los médicos son los que atienden a los pacientes. Visto de ese modo, no serían un tipo de empleado, porque están considerando Empleado como PersonalAdministrativo.

Pero esa no es mi duda central. Mi duda central es respecto a este inciso:
Citarb) Registrar los datos de una cita médica.

En el 1er examen tuve que crear una clase Cliente, y una clase Libro, para relacionarlas (era un sistema como de biblioteca). Pero cuando me pedían ver una "lista de libros solicitados", a pesar que logré implementarlo, siempre tuve la duda de si eso debería ir en un atributo boolean de Libro como "prestado" o en un vector de librosPrestados dentro de la clase Cliente. Además, luego pensé que una biblioteca podría tener también varios libros iguales y prestarlos a distintas personas. Estuve pensando en crear una clase SolicitudLibro.

Y para este ejercicio tal vez una clase CitaMédica. Pero, ¿cómo es la mejor forma de relacionar esto?
Nuestra docente no es nada práctica... es pura teoría, pero no nos enseña a cómo deberíamos pensar los ejercicios. Tal vez CitaMédica podría ser una clase interna de Médico, o de Paciente, o tal vez ir aparte... o tal vez no debería existir y haya otra manera de manejar esto.

¡ ¿Qué es lo más adecuado? !

Por favor, si alguien conoce como tratar estos casos, ayúdeme que le estaré muy agradecido.
#23
Java / Sobre patrón de diseño abstract
19 Octubre 2013, 21:27 PM
Bueno, debo presentar un informe sobre el patrón de diseño abstract.
Y quisiera incluir en él un ejemplo donde sea necesario su uso.

Es decir, he leído la teoría y sé que sirve para crear objetos de manera indirecta. Menciona además que suele usarse cuando no se conoce qué tipo concreto de objeto se va a instanciar, y que ello recién se decide durante la ejecución del programa.

Otra característica indica que se usa cuando es necesario acceder a algún recurso para la creación del objeto. Y esto es lo que no entiendo mucho.

¿Qué ejemplo podría hacer? En el que, si no uso el patrón de diseño abstract, no pueda hacerse el programa correctamente.

----------------------------------------------------------------
Esta es otra duda que tengo:
Si varias clases implementan una interface, ¿todas esas clases son consideradas como de una misma familia? Me parece que la teoría dijese algo así  :silbar:

Gracias de antemano.
#24
Bueno, la verdad es que hasta antes sólo he creado programas pequeños en C++ en consola y algunos otros con interfaz en Windows Forms (Visual Studio 2010).

Como me enteré que en el ciclo entrante llevaré Java pues me he puesto a practicar un poco.
No conozco con exactitud cómo funcionan las clases en Java y tampoco las funciones de las bibliotecas que más suelen usarse... pero apoyado de las advertencias que me daba Netbeans he ido puliendo lo que vendría a ser un juego de la "Snake". Y también basándome un poco en lo que se describe en algunas páginas de referencia.

He conseguido que el programa funcione, es decir, usando las flechas puedo cambiar el sentido de la snake, y esta se desplaza a donde le indique.
Cuando consume un "plus" aumenta su tamaño y reproduce un pequeño sonido (lo mismo hace cuando se estrella contra sí misma). Tiene un sonido de fondo en todo momento, también ...

El .jar puede descargarse de acá:
http://www.mediafire.com/download/e1jvhvph3fa4d38/Snake.jar

Y el código lo copiaré todo a continuación. De seguro se verá un tanto amontonado, porque también incluyo el código generado por el Netbeans cuando se crea un proyecto de Java nuevo y se le agrega un JFrame (y el código que se ha generado mientras yo hacía modificaciones en vista de diseño):
Código (java) [Seleccionar]
package SnakePackage;

import java.applet.AudioClip;
import java.awt.event.ActionEvent; // Complemento para ActionListener.
import java.awt.event.ActionListener; // Para agrupar acciones a desarrollarse.
import java.awt.event.KeyEvent; // Para controlar las pulsaciones del teclado.
import java.util.ArrayList; // Para crear un arreglo dinámico.
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon; // Para añadir imágenes a los JLabel.
import javax.swing.JLabel;
import javax.swing.JOptionPane; // Para mostrar un cuadro de diálogo.
import javax.swing.Timer; // Para controlar el tiempo de desplazamiento.

/**
* @author JCarlos
*/
public class MyMain extends javax.swing.JFrame {

    /**
     * Creates new form MyMain
     */
    public MyMain() {
        this.Sonido_Eat = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/eat.wav") );
        this.Sonido_Fondo = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/music.wav") );
        this.Sonido_Impacto = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/choque.wav") );
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        opt1 = new javax.swing.JRadioButton();
        opt2 = new javax.swing.JRadioButton();
        opt3 = new javax.swing.JRadioButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Snake - By JCRS");
        setMaximumSize(new java.awt.Dimension(350, 280));
        setMinimumSize(new java.awt.Dimension(350, 280));
        setName("MarcoPrincipal"); // NOI18N
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });

        opt1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        opt1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opt1ActionPerformed(evt);
            }
        });

        opt2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        opt2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opt2ActionPerformed(evt);
            }
        });

        opt3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        opt3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opt3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(18, 18, 18)
                .addComponent(opt1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE)
                .addComponent(opt2)
                .addGap(92, 92, 92)
                .addComponent(opt3)
                .addGap(73, 73, 73))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(244, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(opt3)
                    .addComponent(opt2)
                    .addComponent(opt1))
                .addGap(15, 15, 15))
        );

        pack();
    }// </editor-fold>                       

ActionListener MoverIzq = new ActionListener()
{   @Override
    public void actionPerformed(ActionEvent e)
    {
        Body.setLocation(Body.getX()-10, Body.getY());
        ActualizarPosiciones();
        VerificarColision();           
        if(Body.getX()==-10) Body.setLocation(340, Body.getY());
    }
};

ActionListener MoverDer = new ActionListener()
{   @Override
    public void actionPerformed(ActionEvent e)
    {
        Body.setLocation(Body.getX()+10, Body.getY());
        ActualizarPosiciones();
        VerificarColision();
        if(Body.getX()==350) Body.setLocation(0, Body.getY());
    }
};

ActionListener MoverAba = new ActionListener()
{   @Override
    public void actionPerformed(ActionEvent e)
    {
        Body.setLocation(Body.getX(), Body.getY()+10);
        ActualizarPosiciones();
        VerificarColision();
        if(Body.getY()==280) Body.setLocation(Body.getX(), 0);
    }
};

ActionListener MoverArr = new ActionListener()
{   @Override
    public void actionPerformed(ActionEvent e)
    {
        Body.setLocation(Body.getX(), Body.getY()-10);
        ActualizarPosiciones();
        VerificarColision();
        if(Body.getY()==-10) Body.setLocation(Body.getX(), 270);
    }
};

void ActualizarPosiciones()
{
    for(int x=Bloques.size()-1; x>0; --x)
        Bloques.get(x).setLocation(Bloques.get(x-1).getLocation());
    if(Bloques.size()>0)
        Bloques.get(0).setLocation( Body.getLocation() );
    repaint();
}

// ¡Sonidos! Sus direcciones están en el constructor arriba.
AudioClip Sonido_Fondo, Sonido_Eat, Sonido_Impacto;

void VerificarColision()
{
    if(Body.getX() == Plus.getX() && Body.getY() == Plus.getY())
    {
        Sonido_Eat.play();
        JOptionPane.showMessageDialog(new MyMain(), "Ahora el tamaño de la serpiente aumentará, ¡ten cuidado!", "Has conseguido comer un plus.", JOptionPane.INFORMATION_MESSAGE);
        randomizar(Plus);
        CrecerSnake();
    }
   
    for(int i=0; i<Bloques.size()-1; ++i)
        for(int j=i+1; j<Bloques.size(); ++j)
            if(Bloques.get(i).getX()==Bloques.get(j).getX() && Bloques.get(i).getY()==Bloques.get(j).getY())
            {
                Sonido_Impacto.play();
                Perdiste();
            }
}   

void Perdiste()
{
    JOptionPane.showMessageDialog(new MyMain(), "¡Lo siento mucho! Has perdido.\n\tPuntuación: "+Bloques.size(), "Game Over.", JOptionPane.INFORMATION_MESSAGE);
    // randomizar(Plus);
    Temporizador.stop();
    for(int i=0; i<Bloques.size(); ++i)
        this.getContentPane().remove(Bloques.get(i));
    Bloques.clear();
    this.getContentPane().remove( Body );
    this.getContentPane().remove( Plus );
    Menu.setVisible(true);
    opt1.setVisible(true);
    opt2.setVisible(true);
    opt3.setVisible(true);
   
}

        ArrayList<JLabel> Bloques = new ArrayList<>(); // Creamos el arreglo vacío.

void CrecerSnake()
{
    JLabel Nuevo = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/body.gif")) );
    //Nuevo.setLocation(0, 0);
    Nuevo.setSize(10, 10);
    Bloques.add( Nuevo );
    this.getContentPane().add( Bloques.get( Bloques.size()-1 ) );       
}

Timer Temporizador = new Timer(1000, null); // int delay, ActionListener listener
           
    private void formKeyPressed(java.awt.event.KeyEvent evt) {                               
        if(
             (evt.getKeyCode() == KeyEvent.VK_LEFT
             || evt.getKeyCode() == KeyEvent.VK_RIGHT
             || evt.getKeyCode() == KeyEvent.VK_DOWN
             || evt.getKeyCode() == KeyEvent.VK_UP
             || evt.getKeyCode() == KeyEvent.VK_V)
             && Temporizador.getActionListeners().length > 0
           )
            Temporizador.removeActionListener(Temporizador.getActionListeners()[0]);
        if(evt.getKeyCode() == KeyEvent.VK_LEFT)
        {
            Temporizador.addActionListener(MoverIzq);
            //JOptionPane.showMessageDialog(this, "Has presionado la tecla con una flecha hacia la izquierda.", "Tecla presionada.", JOptionPane.INFORMATION_MESSAGE);
        }
        if(evt.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            Temporizador.addActionListener(MoverDer);
        }
        if(evt.getKeyCode() == KeyEvent.VK_DOWN)
        {
            Temporizador.addActionListener(MoverAba);
        }
        if(evt.getKeyCode() == KeyEvent.VK_UP)
        {
            Temporizador.addActionListener(MoverArr);
        }
        if(evt.getKeyCode() == KeyEvent.VK_V)
        { // Muestra las posiciones.
            JOptionPane.showMessageDialog(new MyMain(), "Posición de Body: "+Body.getX()+", "+Body.getY()+"\nPosición de Plus: "+Plus.getX()+", "+Plus.getY(), "Game Over.", JOptionPane.CLOSED_OPTION);
        }
    }                               

int XAleatorio()
{
    return (int)(Math.random() * (34 + 1))*10;
}
int YAleatorio()
{
    return (int)(Math.random() * (27 + 1))*10;
}

void randomizar(JLabel L)
{
    L.setLocation(XAleatorio(), YAleatorio());
}

    JLabel Body = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/body.gif")) );
    JLabel Plus = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/plus.png")) );
   
    void EmpezarJuego(int velocidad)
    {     
        // Limpiamos componentes del menú.
        Menu.setVisible(false);
        opt1.setVisible(false);
        opt2.setVisible(false);
        opt3.setVisible(false);
       
        Temporizador.setDelay(velocidad);
        Temporizador.start();
       
        Body.setSize(10, 10); Plus.setSize(10, 10);
       
        this.getContentPane().add( Body );
        this.getContentPane().add( Plus );
       
        randomizar(Body);
        randomizar(Plus);
    }
   
    JLabel Menu = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/Start.jpg")) );
       
    private void formWindowOpened(java.awt.event.WindowEvent evt) {                                 
        Sonido_Fondo.loop();
       
        Menu.setSize(350, 280);
        this.getContentPane().add(Menu);
        Menu.setLocation(0, 0); repaint();
       
        ButtonGroup grupoBotonesOpcion = new ButtonGroup();
        grupoBotonesOpcion.add( opt1 );
        grupoBotonesOpcion.add( opt2 );
        grupoBotonesOpcion.add( opt3 );
    }                                 

    private void opt1ActionPerformed(java.awt.event.ActionEvent evt) {                                     
        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo fácil?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
        {
            EmpezarJuego(120);
        }
    }                                   

    private void opt2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo medio dificultoso?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
        {
            EmpezarJuego(80);
        }
    }                                   

    private void opt3ActionPerformed(java.awt.event.ActionEvent evt) {                                     
        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo difícil?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
        {
            EmpezarJuego(60);
        }        // TODO add your handling code here:
    }                                   

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MyMain().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JRadioButton opt1;
    private javax.swing.JRadioButton opt2;
    private javax.swing.JRadioButton opt3;
    // End of variables declaration                   
}


¿Cuál es el problema?
Bueno quisiera que me ayuden a entender las razones de por qué el programa se detiene repentinamente luego que se han consumido unas 12-14 veces el plus (la canción de fondo sigue reproduciéndose pero la Snake no obedece, es decir, no se desplaza por más que presione las flechas del teclado).
En el título he puesto Garbage Collector porque no se me ocurría otra cosa que pudiera detener el funcionamiento... pero la verdad es que tampoco estoy muy seguro de esto, pues C++ no tiene un recolector de basura por defecto. ¿Será que el recolector termina por borrar el Timer y por ello ya no ejecuta las acciones? Porque el programa no es que se haya "colgado", sino que las acciones de desplazamiento es como si hubiera dejado de existir.

Gracias y espero puedan orientarme un poco.
#25
¿Cómo puedo agregar un JLabel en tiempo de ejecución?

Es decir, en el momento de que "suceda algo" quiero que aparezca una imagen en una posición determinada.
Quisiera que el JLabel se cree en ese instante y se muestre en una posición que yo elija basándome en datos que se han obtenido en tiempo de ejecución.
No quisiera respuestas como "créalo oculto y luego muéstralo" porque de seguro es posible crearlo al instante, sólo que no tengo idea de cómo  :silbar:

Gracias de antemano ...
#26
Iba a responder (preguntando) en el tema que corresponde al siguiente enlace:
Citarhttp://foro.elhacker.net/programacion_cc/es_necesario_stdafxh-t292167.0.html
Pero como saltó una advertencia diciendo que el tema es antiguo he creado este otro.

Agradecería mucho que alguien pueda aclarar un poco más este tema.
Es decir, ¿qué tan necesario es usar el "stdafx.h"? ¿qué tan beneficioso resulta usar una cabecera precompilada?

He visto que esa opción se puede quitar pero no sé si sea recomendable.

¿Usar "stdafx.h" es salirse de lo "estándar"?

Tengo instalados el MinGW, Visual Studio y Code::Blocks.
He estado usando los tres, pero creo que debería decidirme por uno  :silbar:
#27
Hay un juego en el que se requiere escribir el nombre de un spell y presionar enter para que mi personaje ejecute dicho hechizo.
Del mismo modo, debo usar las pociones para curarle la maná (energía).

De por sí todo eso es tedioso, pero el mismo juego incluye hotkeys personalizables. Es decir, presionando F1 puedo usar el hechizo para crear blank runes (runas vacías), y presionando F2 otro hechizo para convertir esa runa vacía en una runa SD (sudden death) que me sirve para luego pegar hits que hacen un buen daño.

Bueno, el punto es que yo no pretendo estar sentado en mi ordenador haciendo F1 y F2 cuando sea necesario.

Aprovechando que sé cada cuanto tiempo debo presionar cada una de esas teclas, quisiera crear un programa que las "presione" por mí.

Yo conozco algo de C++... pero antes de preguntar en el foro respectivo de ese lenguaje, quería saber si hay alguna forma más sencilla de hacerlo con algún lenguaje de script. Porque tengo entendido que, por ejemplo los archivos de extensión .bat no necesitan compilarse. Sólo se guardan y con eso basta para poder ejecutarse.

Gracias de antemano !
#28
Quisiera saber cómo activar la notificación instantánea en el foro. Es decir, quisiera que me llegue una notificación a mi correo cada vez que hay un nuevo post en los thread que he participado.
Gracias de antemano.
#29
Desconozco totalmente a Linux. Siempre he usado Windows, y nunca he tenido la oportunidad de tratar con algún ordenador que traiga a Linux consigo.

Quizás pensarán que vivo en un país muy muy desactualizado. Pero está bien, no me incomoda, porque es cierto.

Ahora, lo que quisiera saber es qué tan difícil es tratar con uno (para alguien tan desinformando como yo). ¿Es necesario ver tutoriales, guías? O quizás hasta preciso seguir cursos antes de poder usarlo.

Gracias de antemano.